AsyncTask: 把值传递给一个Activity(onCreate方法)

3

Update1

activity:

public Integer _number = 0;
@Override
    public void onCreate(Bundle savedInstanceState) {
if (_number >0)
        {
            Log.d("onSuccessfulExecute", ""+_number);
        }
        else
        {
            Log.d("onSuccessfulExecute", "nope empty songs lists");
        }
}

public int onSuccessfulExecute(int numberOfSongList) {

_number = numberOfSongList;

if (numberOfSongList >0)
{
    Log.d("onSuccessfulExecute", ""+numberOfSongList);
}
else
{
    Log.d("onSuccessfulExecute", "nope empty songs lists");
}
    return numberOfSongList;
}

更新1结束

更新:AsynchTask有自己的外部类。

如何从AsyncTask的onPostExecute()传递一个值...到activity中

我的代码确实可以从onPostExecute()返回值并在UI上进行更新,但我正在寻找一种设置来自AsynchTask的活动变量(NumberOfSongList)的方法。

AsyncTask类:

@Override
    public void onPostExecute(asynctask.Payload payload)
    {  
         AsyncTemplateActivity app = (AsyncTemplateActivity) payload.data[0];

             //the below code DOES UPDATE the UI textView control
             int answer = ((Integer) payload.result).intValue();
             app.taskStatus.setText("Success: answer = "+answer);

            //PROBLEM:
            //i am trying to populate the value to an variable but does not seems like the way i am            doing:
            app.NumberOfSongList = payload.answer;
            ..............
            ..............
    }

活动:

  public Integer NumberOfSongList;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 

        //Several UI Code   
        new ConnectingTask().execute();
        Log.d("onCreate", ""+NumberOfSongList);

    } 

如果你期望在那个 Log.v() 调用中看到 NumberOfSongsList,可能不会发生,因为 AsyncTask 没有完成它的工作。那个 asynctask.PayLoad 响应到底是什么? - user
它肯定不会在你展示的Log.d("onCreate....")中更新。asyncTask和线程的开销将确保这一点。你有检查过程序后面的值是否更新了吗? - eyespyus
是的,它在log.d上没有更新,我知道这一点...这就是为什么我需要帮助...是的,在onPostExecute中它更新了值,我可以看到它但在活动中看不到。 - Nick Kahn
3个回答

2
使用setter方法如何?例如:
private int _number;
public int setNumber(int number) {
    _number = number;
}

更新:

请看这段代码。这将实现你想要完成的目标。

活动类

public class TestActivity extends Activity {
    public int Number;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.test);

        Button btnDisplay = (Button) findViewById(R.id.btnDisplay);
        btnDisplay.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                Toast toast = Toast.makeText(v.getContext(), "Generated number: " + String.valueOf(Number), Toast.LENGTH_LONG);
                toast.show();               
            }
        });

        new TestTask(this).execute();
    }
}

异步任务类

public class TestTask extends AsyncTask<Void, Void, Integer> {
    private final Context _context;
    private final String TAG = "TestTask";
    private final Random _rnd;

    public TestTask(Context context){
        _context = context;
        _rnd = new Random();
    }

    @Override
    protected void onPreExecute() {
        //TODO: Do task init.
        super.onPreExecute();
    }

    @Override
    protected Integer doInBackground(Void... params) {
        //Simulate a long-running procedure.
        try {
            Thread.sleep(3000);         
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage());
        }

        return _rnd.nextInt();
    }

    @Override
    protected void onPostExecute(Integer result) {
        TestActivity test = (TestActivity) _context;
        test.Number = result;       
        super.onPostExecute(result);
    }
}

这也行不通,因为AsyncTask没有完成工作,正如slukian指出的那样,这是有道理的,我在调试时也注意到了。 - Nick Kahn
谢谢,但我有一个问题,为什么需要硬编码活动名称 TestActivity test = (TestActivity) _context; 我正在处理一个任何活动都应该能够调用的类,但如果按照您的方法进行,我发现活动是硬编码的... 有什么想法吗? - Nick Kahn
上下文可以是任何Activity,我只是使用TestActivity来快速演示访问我的活动字段。 - Mauro

1
仅供参考:当尝试在AsyncTask中保存Activity实例的引用时,请非常小心 - 我以前吃过亏:)。如果用户在后台任务仍在运行时旋转设备,则Activity将被销毁并重新创建,从而使对Activity的引用失效。

正如您所看到的,我一直在努力使AsyncTask拥有自己的类,而不是作为活动的子类,但似乎非常具有挑战性... 我开始意识到拥有自己的类与拥有子类并没有什么区别。你有什么想法吗? - Nick Kahn
你能告诉我AsyncTask正在执行什么类型的函数吗?(调用Web服务等)? - px3j
我建议按照下面的帖子所建议的做法,为您的Activity添加一个setter方法,然后在调试器中设置一个断点,看看setter是否被调用。但请记住,在执行doInBackground()方法时,Activity可能会被销毁/重新创建,因此您必须处理这种情况。我发现这个视频非常有启发性:链接 - px3j

0
创建监听器。 创建一个新的类文件。将其命名为MyAsyncListener之类的名称,并使其看起来像这样:
 public interface MyAsyncListener() {
      onSuccessfulExecute(int numberOfSongList);
 }

让您的活动实现MyAsyncListener,即

 public class myActivity extends Activity implements MyAsyncListener {

将监听器添加到AsyncTask的构造函数中,并将其设置为Async类中的全局变量。然后在onPostExecute中调用监听器的方法并传递数据。
 public class MyCustomAsync extends AsyncTask<Void,Void,Void> {

      MyAsyncListener mal;

      public MyCustomAsync(MyAsyncListener listener) {
           this.mal = listener;
      }

      @Override
      public void onPostExecute(asynctask.Payload payload) {
           \\update UI
           mal.onSuccessfulExecute(int numberOfSongList);
      }
 }

现在,每当您的AsyncTask完成时,它将调用Activity类中的onSuccessfulExecute方法,该方法应如下所示:

 @Override
 public void onSuccessfulExecute(int numberOfSongList) {
      \\do whatever
 }

祝你好运。


不起作用...没有错误,但是没有显示值..我会更新问题 - Nick Kahn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接