如何管理需要由 AsyncTask 调用的不同任务

Posted

技术标签:

【中文标题】如何管理需要由 AsyncTask 调用的不同任务【英文标题】:How to manage different task which need to be called by AsyncTask 【发布时间】:2016-03-18 09:37:30 【问题描述】:

我有一个外部库可以使用,它通过互联网与服务器通信。每次我需要从互联网上获取一些信息时,android 都会强迫我使用 asynctask。到目前为止没有问题。但是,我收到越来越多的任务来(以不同的方式)从互联网上检索数据,而且我不喜欢为每个单独的呼叫增加不同的类。 长话短说:我有不同的互联网呼叫,而不是为每个呼叫创建一个异步任务类,我更喜欢一个类来管理所有不同的呼叫。这有可能吗?更重要的是,这样做的正确方法是什么?

【问题讨论】:

Android 不会强迫您使用 AsyncTasks - 有很多方法可以调用 Web 服务。也许像 Retrofit 这样的东西会有所帮助:github.com/square/retrofit 【参考方案1】:

我也面临像你一样的问题。但我通过反射技术解决了这个问题。我已经制定了一种方法来防止增加不同的类来调用单次命中。 我制作了单个 asynctask 类并传递了活动的函数名称和上下文,并通过 onPostExecute 返回了响应。

这里是示例 -

AsyncTaskConnection.java

public class AsyncTaskConnection extends AsyncTask<String, String, Object>
    JSONObject mainObject;
    Context mContext;
    String returnFunctionName;

    public AsyncTaskConnection (Context context)
         mContext = context;
    

    protected void onPreExecute() 
        // preExecute
    

    @Override
    protected Object doInBackground(String... arguments) 
        String apiFunctionName = arguments[0]; // get api FunctionName 
        String jsonString = arguments[1]; // get data
        returnFunctionName = apiFunctionName+"Response"; // return function name
        // some connection code...


        //then call...
            try 
                ht.call(NAMESPACE, requestEnvelop);
             catch (IOException ex) 
                Log.d(mContext.getClass().getName(), "Io exception bufferediostream closed" + ex);
                ex.printStackTrace();
            
            return mainObject.toString();
         catch (Exception e) 
            Log.d("Exception", e.toString());
            return "no";
        
    

    // main thing is there, i have use the reflaction here....

    @Override
    protected void onPostExecute(Object backresult) 
        Method m;
        try 

            m = mContext.getClass().getDeclaredMethod(returnFunctionName, String.class);
            m.invoke(mContext, (String) backresult);
         catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) 
            e.printStackTrace();
         catch (NoSuchMethodException e) 
            e.printStackTrace();
        
    

在调用者类中

//call this class where you want and get dynamic response 
new AsyncTaskConnection(this).execute("getHomepage",jo.toString());

// and make response fuction

protected void getHomepageResponse(String backresult) 
            try 
// this is your response
                mainObject = new JSONObject(backresult);
             catch (JSONException e) 
                e.printStackTrace();
            
        

而且有很多方法可以得到你想要的结果。

【讨论】:

没关系,如果你有一个电话。我的网络任务稍微复杂一些。但是,我会尝试做这样的事情。问题是,我有 20 行代码都依赖于网络连接的响应,然后我不能在主线程中等待响应。你知道我的意思吗? 你到底想要什么@RobertStettler 我没明白。你能解释一下吗 “我有 20 行代码,它们都依赖于网络连接的响应”,@RobertStettler 你能否在代码级别对这些行进行更多解释然后也许,我会得到你的问题很明显.. 我想我知道如何处理它。每个超过 1 行代码的调用我都可以简单地作为方法添加到 AsynTaskConnection 类,并使用您的解决方案调用该方法。我只需要分组然后一起。【参考方案2】:

是的,这是可能的,但您需要创建一些通用的 AsyncTask,在收到结果时接收 API(要调用的 URL)和处理程序。

异步类:

public class AsyncTaskThread extends AsyncTask<Object, Object, Object> 
    //instance variables
    Handler myHandler;
    public AsyncTaskThread(String uriString, Handler myHandler) 
       //set these arguments to respective instance variables 
       this.myHandler=myHandler;
    
      protected Object doInBackground(Object... obj)
          //business  logic
      
    //----implement other  methods of Async as per your requirement
      @Override
    protected void onPostExecute(Object result) 
          super.onPostExecute(result);
          Message message = new Message();
          message.obj = result;
          myHandler.sendMessage(message);

线程的传递处理程序: 您需要在参数中将处理程序传递给上述异步任务。

new AsyncTaskThread(uri,new MyHandler())

import android.os.Handler;
private class MyHandler extends Handler
        @Override
        public void handleMessage(Message msg) 
            Model response = (Model) msg.obj;
        

当收到结果时,从您的异步任务传递的处理程序上调用 sendMessage() 方法。

我的建议: 如果您使用 okhttp 客户端库进行 API 调用,请参阅https://github.com/square/okhttp/wiki/Recipes

【讨论】:

谢谢,我不明白 //-- 实现方法的含义是什么?我想你只能有一个 doinbackground,不是吗? 我已经编辑了帖子,我的意思是它是为了实现异步类的其他方法 这不是我的问题:afaik 每个班级只能有一个“doinbackground”方法.... 是的,我忘记写了。扩展 Async 的子类至少覆盖 doInBackground()

以上是关于如何管理需要由 AsyncTask 调用的不同任务的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android开发中用AsyncTask异步更新UI界面

Android:AsyncTask 需要一个上下文来在离开包含活动后显示警报

如何在viewmodel中的异步任务后更新UI

Android线程管理之AsyncTask异步任务

由 AsyncTask 调用时 ProgressDialog.dimiss 方法出错

我如何在异步任务中进行ksoap2调用?