代码之家  ›  专栏  ›  技术社区  ›  Christian Wolf Alves Hess

从asynctask回调回activity[重复]

  •  -2
  • Christian Wolf Alves Hess  · 技术社区  · 7 年前

    我目前正在为我大学的一个项目开发一个应用程序。该项目由我组成,能够处理对我构建的web服务的同步和非同步http请求。我必须创建一个类或一些代码,可以发送http请求(通过AsyncTask轻松完成),并将响应回调到活动。

    我不知道该怎么做,因为onPostExecute()方法是一个void方法,它不会返回任何内容,而且我无法将响应的内容保存在公共变量中,因为它在另一个类中。

    我想做的是:

    来自活动:

    MessageCentre centre = new MessageCentre();
    centre.getMessages(1); 
    

    1是登录到我的应用服务器的该设备的Id。然后,服务器以JSONArray格式检索与该ID相关联的所有消息。我将这些JSONObject转换为我构建的消息类,并将所有这些新对象保存为MessageCentre类实例内的静态数组。

    从这里开始,我必须向用户显示消息,但我不能这样做,因为在getMessages(1)方法中,我执行了一个AsyncTask,它在我的应用程序中生成了一个辅助线程。代码如下所示,但ArrayAdapter不显示消息(因为他在消息从应用服务器到达之前呈现适配器)

    ArrayAdapter a = new ArrayAdapter(getApplicationContext(),R.id.item_layout, centre.getMessagesList());
    listview.setAdapter(a);
    

    我也不想从AsyncTask中设置适配器,因为我希望以“黑匣子”格式进行设置,用户只需调用方法并通过接收普通对象数组“使其工作”,然后在此基础上实现自己的视图。

    我也不能简单地通过执行线程来告诉活动等待几秒钟。sleep(),因为这会使应用程序崩溃并显示ANR错误。

    因此,我可以想出一些方法来处理这个问题:

    1) 一种使活动在没有ANR的情况下等待一段时间的方法

    2) 在某种回调方法中,以非onPostExecute()方法的方式将数据返回给活动

    3) 使适配器和listview能够在运行时更新和创建ITEN(OnCreateView()方法),以在设置和呈现消息后,在消息实际到达时,几秒钟后,从应用服务器显示消息。

    非常感谢大家的帮助,非常感谢!

    1 回复  |  直到 7 年前
        1
  •  3
  •   dotGitignore    7 年前

    您可以创建 interface 进行回调。

    创建类 AsyncTaskMessage

    public class AsyncTaskMessage extends AsyncTask<Void, Void, Void> {
    
    
        Context context;
        public OnMessageListener mListener;
    
        public interface OnMessageListener {
            void messageCallback(ArrayList<String> messageList); // you can change the parameter here. depends on what you want.
        }
    
        public AsyncTaskMessage(Context context) {
            this.context = context;
            mListener = (OnMessageListener) context;
        }
    
        @Override
        public void onPreExecute() {
    
        }
    
        @Override 
        protected void onPostExecute() {
            // your code goes here for the callback.
            // messageList - A list of messages.
            mListener.messageCallback(messageList);
        }
    }
    

    然后你的 MessageCentre 类别:

    public class MessageCentre {
    
        Context context;
        public void MessageCentre(Context context) {
            this.context = context;
        }
    
        public void getMessages(int id) {
            // You said your asyncTask goes here.
            AsyncTaskMessage async = new AsyncTaskMessage(context);
            async.execute();
        }
    }
    

    ArrayAdapter

    // A class where your ArrrayAdapter.
    public class MainActivity extends AppCompatActivity implements AsyncTaskMessage.OnMessageListener {
    
        //.. 
    
        public void displayMessage() {
            MessageCentre centre = new MessageCentre(this);
            centre.getMessages(1); 
        }
    
        @Override
        public void messageCallback(ArrayList<String> messageList) {
            Log.i("MainActivity", "Response: " + messageList.toString());
            ArrayAdapter a = new ArrayAdapter(getApplicationContext(),R.id.item_layout, messageList);
            listview.setAdapter(a);
        }
    }