Android:如果AsyncTask在一个单独的类中,如何从AsyncTask更新UI?

rea*_*ebo 36 android updates android-asynctask android-activity

我讨厌内心阶级.

我有一个主要的活动是推出'短命'AsyncTask.

AsyncTask 位于单独的文件中,不是主要活动的内部类

我需要异步任务更新主Activity的textView.

我知道如果AsyncTask是内部类,我可以从onProgressUpdate更新TextView

但是,如何从外部,独立,异步的任务?

更新:这看起来像工作:

在活动中,我称之为任务

backgroundTask = new BackgroundTask(this);
backgroundTask.execute();
Run Code Online (Sandbox Code Playgroud)

在我的构造函数中

public BackgroundTask(Activity myContext)
{
    debug = (TextView) myContext.findViewById(R.id.debugText);
}
Run Code Online (Sandbox Code Playgroud)

其中debug是AsyncTask的私有字段.

所以onProgressUpdate我可以

debug.append(text);
Run Code Online (Sandbox Code Playgroud)

谢谢你们所有的建议

Mar*_*ski 37

编辑我编辑了使用的答案WeakReference


AsyncTask始终是独立的类Activity,但我怀疑你的意思是它与你的活动类文件在不同的文件中,所以你不能从活动的内部类中受益.只需将Activity上下文作为参数传递给您的异步任务(即它的构造函数)

class MyAsyncTask extends AsyncTask<URL, Integer, Long> {

    WeakReference<Activity> mWeakActivity;

    public MyAsyncTask(Activity activity) {
       mWeakActivity = new WeakReference<Activity>(activity);
    }

 ...
Run Code Online (Sandbox Code Playgroud)

并在需要时使用(记住不要在使用期间使用doInBackground()),即通常打电话时

int id = findViewById(...)
Run Code Online (Sandbox Code Playgroud)

在AsyncTask中你调用ie

Activity activity = mWeakActivity.get();
if (activity != null) {
   int id = activity.findViewById(...);
}
Run Code Online (Sandbox Code Playgroud)

请注意,我们Activity可以doInBackground()在正在进行时消失(因此返回的引用可以变为null),但是通过使用WeakReference我们不会阻止GC收集它(以及泄漏内存)并且随着Activity的消失,甚至尝试更新它通常也没有意义状态(仍然,根据您的逻辑,您可能希望执行诸如更改内部状态或更新数据库之类的操作,但必须跳过触摸UI).

  • 如果你走这条路线,最好把活动参考作为WeakReference <Activity>而不仅仅是Activity.IMO. (2认同)

小智 21

使用接口1)创建一个接口

public interface OnDataSendToActivity {
    public void sendData(String str);
}
Run Code Online (Sandbox Code Playgroud)

2)在你的Activity中实现它

public class MainActivity extends Activity implements OnDataSendToActivity{

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          new AsyncTest(this).execute(new String[]{"AnyData"}); // start your task
     }

     @Override
     public void sendData(String str) {
         // TODO Auto-generated method stub

     }

}
Run Code Online (Sandbox Code Playgroud)

3)在AsyncTask中创建构造函数(Activity activity){}在AsyncTask文件中注册接口并调用interface方法,如下所示.

public class AsyncTest extends AsyncTask<String, Integer, String> {

    OnDataSendToActivity dataSendToActivity;
    public AsyncTest(Activity activity){
        dataSendToActivity = (OnDataSendToActivity)activity;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        dataSendToActivity.sendData(result);
    }

}
Run Code Online (Sandbox Code Playgroud)

在这里,你的OnPostExecute将在AsyncTask完成的所有任务之后调用,并将获得"result"作为参数,由doInBackground(){return"";}返回.

而"dataSendToActivity.sendData(result);" 它将调用activity的重写方法"public void sendData(String str){}".

要记住的边缘情况:确保传递this,即您当前活动的上下文,AsyncTask而不是创建您的活动的另一个实例,否则您Activity将被销毁并创建新的实例.


pyu*_*s13 5

在您的 Activity 类中创建一个静态函数,传递上下文以更新您的文本视图,然后在 AsynkTask 类中调用此函数进行更新。

在 Activity 类中: public static void updateTextView(){

//这里是你的代码 }

在 AynckTask 类中调用此函数。