从公共类中的AsyncTask更新UI线程

时间:2013-08-28 04:17:03

标签: android android-asynctask

我正在尝试将一些AsyncTask类拆分为公共(单独)函数,这样我就不必重写那么多代码了。我几乎拥有它,除了一个非常重要的方面。 AsyncTask函数通过对服务器进行php调用来编译ArrayList。完成此列表后,我需要更新主UI线程上的微调器。我找到了一个非常好的答案here,但我在使它工作时遇到了一些困难。

以下是我所拥有的缩小版本:(请注意,此时,我要做的就是调用Toast消息来证明往返行程正常工作)

这是调用Activity

public class MyActivity extends Activity implements OnTaskCompleted {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sg_list = new ArrayList<String>();
        new GetSuperGroups(UpdateAffiliationsPreferences.this, context, "Retrieving Group List...").execute();
    }

    public void onTaskCompleted(ArrayList<String> list) {
        Toast.makeText(getApplicationContext(), "hello from async", Toast.LENGTH_SHORT).show();
    }

}

这是界面:

public interface OnTaskCompleted {
    void onTaskCompleted(ArrayList<String> list);
}

最后,这是AsyncTask。请注意,它是一个Public类:

public class GetSuperGroups extends AsyncTask<String, String, ArrayList<String>> {

    private Activity activity;
    private Context context;
    private String progressMsg;
    private ProgressDialog pDialog;
    private ArrayList<String> sg_list;
    private OnTaskCompleted listener;

    public GetSuperGroups(Activity activity, Context context, String progressMsg) {
        this.activity = activity;
        this.context = context;
        this.progressMsg = progressMsg;
    }

    public void setSuperGroupList (OnTaskCompleted listener){
        this.listener = listener;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(context);
        pDialog.setMessage(progressMsg);
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected ArrayList<String> doInBackground(String... args) {

        sg_list = new ArrayList<String>();
        //make a php call, compile the ArrayList    
        return sg_list;
    }

    protected void onPostExecute(ArrayList<String> sg_list) {
        pDialog.dismiss();
        //this next line causes a null pointer error
        //note that I am throwing away the array list for now
        //all I want to do is prove that I can call the Toast back in the calling Activity
        listener.onTaskCompleted(new ArrayList<String>());
    }
}

4 个答案:

答案 0 :(得分:7)

只需在OnTaskCompleted listener asyncTask constructor中添加GetSuperGroups参数即可。然后在执行this时传递asyncTask

public class MyActivity extends Activity implements OnTaskCompleted {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            sg_list = new ArrayList<String>();
            new GetSuperGroups(UpdateAffiliationsPreferences.this, context, "Retrieving Group List...", this).execute();
        }

        public void onTaskCompleted(ArrayList<String> list) {
            Toast.makeText(getApplicationContext(), "hello from async", Toast.LENGTH_SHORT).show();
        }

    }

  public class GetSuperGroups extends AsyncTask<String, String, ArrayList<String>> {

        private Activity activity;
        private Context context;
        private String progressMsg;
        private ProgressDialog pDialog;
        private ArrayList<String> sg_list;
        private OnTaskCompleted listener;

        public GetSuperGroups(Activity activity, Context context, String progressMsg, OnTaskCompleted listener) {
            this.activity = activity;
            this.context = context;
            this.progressMsg = progressMsg;
            this.listener = listener;
        }

答案 1 :(得分:2)

您永远不会致电setSuperGroupList(),因此listener仍然为空。最好将监听器放入任务的构造函数中。

答案 2 :(得分:0)

你走了正确的道路。但我不清楚onPostExecute(..)方法中的问题。它是关于null pDialog还是null sg_list。如果sg_list中的问题请检查php方法是否有效?可能是php服务清单文件中的权限问题 所以我建议首先在UI线程上检查你的方法。然后将其更改为后台线程 您也可以在toPostExecute方法中使用toast来检查sg_list内容。

答案 3 :(得分:0)

您需要添加一个函数setListener:

public class TaskComplete {
    public OnTaskCompleted onTaskListenerComplete;

    public interface OnTaskCompleted {
        void onTaskCompleted(ArrayList<String> list);
    }

    public void setOnTaskComplete(OnTaskCompleted onTaskListenerComplete){
        this.onTaskListenerComplete = onTaskListenerComplete;
    }
}

在Activity中,定义并设置它:

public class MyActivity extends Activity implements OnTaskCompleted {
    public TaskComplete task;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sg_list = new ArrayList<String>();
        task.setOnTaskComplete(this);
        new GetSuperGroups(UpdateAffiliationsPreferences.this, context, "Retrieving Group List...").execute();
    }

    public void onTaskCompleted(ArrayList<String> list) {
        Toast.makeText(getApplicationContext(), "hello from async", Toast.LENGTH_SHORT).show();
    }

}

在AsyncTask中:

protected void onPostExecute(ArrayList<String> sg_list) {
    pDialog.dismiss();
    //this next line causes a null pointer error
    //note that I am throwing away the array list for now
    //all I want to do is prove that I can call the Toast back in the calling Activity
    activity.onTaskCompleted(new ArrayList<String>());
}

希望它有用。