使用回调接口实现AsyncTask - 在单个回调接口中处理多个呼叫响应

时间:2017-01-16 09:40:02

标签: android android-asynctask

在我的Android应用程序中,我正在从一个Activity进行多个API调用。我使用以下方法:在Activity中实现接口并从Async类调用该接口函数。

public interface AsyncResponse {
    public void processFinish(JSONObject sb);
}


public class FetchData extends AsyncTask<String, Integer, JSONObject> {
    HttpURLConnection urlConnection;
    String url;
    String method;
    String payload = null;
    AsyncResponse delegate = null;

    public FetchData(AsyncResponse delegate, String url, String method) {
        this.delegate = delegate;
        this.url = url;
        this.method = method;
    }

    public FetchData(AsyncResponse delegate, String url, String method, JSONObject payload) {
        this(delegate, url, method);
        this.payload = payload.toString();
    }

    @Override
    protected JSONObject doInBackground(String... args) {
        BufferedReader reader = null;

        try {
            URL url = new URL(this.url);

            // Open HTTP connection
            urlConnection = (HttpURLConnection) url.openConnection();

            // HTTP method GET/POST/PUT/DELETE
            urlConnection.setRequestMethod(this.method); 

            // handle issues
            int statusCode = urlConnection.getResponseCode();

            // Get the response
            InputStream inputStream = urlConnection.getInputStream();
            if(inputStream == null) {
                // Nothing to do
                return null;
            }
            reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String inputLine = null;
            StringBuffer response = new StringBuffer();

            while ((inputLine = reader.readLine()) != null) {
                response.append(inputLine + "\n");
            }

            return new JSONObject(response.toString());
        } catch(Exception e) {
            try {
                // Return error response
            } catch(Exception e1) {
                System.out.println(e1);
                return null;
            }
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e("PlaceholderFragment", "Error closing stream", e);
                }
            }
        }
    }

    @Override
    protected void onPostExecute(JSONObject result) {
        super.onPostExecute(result);
        this.delegate.processFinish(result);
    }
}


public class AsyncTasks extends AppCompatActivity implements AsyncResponse {
    TextView view = null;
    int a = 1;
    Utility utility = Utility.getInstance();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_tasks);
        new FetchData(this, "<url 1>", "GET").executeOnExecutor(THREAD_POOL_EXECUTOR);

        new FetchData(this, "<url 2>", "GET").executeOnExecutor(THREAD_POOL_EXECUTOR);
    }

    @Override
    public void processFinish(JSONObject data) {
        utility.showDialog(this, data.toString());
    }
}

这里如何处理 processFinish()接口函数中第二个GET调用的响应?什么是最好的方法?

2 个答案:

答案 0 :(得分:2)

public interface AsyncResponse {
    //Add requestCode to identify request.  
    public void processFinish(JSONObject sb, int requestCode);
}


public class FetchData extends AsyncTask<String, Integer, JSONObject> {
    HttpURLConnection urlConnection;
    String url;
    String method;
    String payload = null;
    AsyncResponse delegate = null;
    int requestCode;

    public FetchData(String url, String method) {
        this(url, method, null);
    }

    public FetchData(String url, String method, JSONObject payload) {
        this.url = url;
        this.method = method;
        if(payload!=null){
             this.payload = payload.toString();
        }
    }

    //You can set AsyncResponse and RequestCode in constructor also.
    public FetchData setListener(AsyncResponse asyncResponse, int requestCode){
        this.delegate = asyncResponse;
        this.requestCode = requestCode;
        return this;
    }

    @Override
    protected JSONObject doInBackground(String... args) {
        ....
    }

    @Override
    protected void onPostExecute(JSONObject result) {
        super.onPostExecute(result);
        if(delegate!=null){        
            //post result with given requestCode
            this.delegate.processFinish(result, requestCode);
        }
    }
}


public class AsyncTasks extends AppCompatActivity implements AsyncResponse {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_tasks);

        // Make first call with request code as 1    
        new FetchData("<url 1>", "GET").setListener(this, 1).executeOnExecutor(THREAD_POOL_EXECUTOR);

        // Make second call with request code as 2
        new FetchData("<url 2>", "GET").setListener(this, 2).executeOnExecutor(THREAD_POOL_EXECUTOR);
    }

    @Override
    public void processFinish(JSONObject data, int requestCode) {
        switch(requestCode){
            case 1:
            //perform task on 1st call finish
            break;
            case 2:
            utility.showDialog(this, data.toString());
            //perform task on 2nd call finish
            break;
        }
    }
}

答案 1 :(得分:0)

也许我来晚了。 但是我遇到了与您相同的问题,经过验证的答案中的这种切换案例令人震惊,因此在这里您可以找到一种使用匿名AsyncResponse对任意数量的请求实施该方法的方法。

当您通过实现processFinish方法传递AsyncTasks类来管理回调时,在获取数据时,请使用新的AsyncResponse对其进行更改并在该方法中实现。

赞!

public interface AsyncResponse {
    //Add requestCode to identify request.  
    public void processFinish(JSONObject sb, int requestCode);
}


public class FetchData extends AsyncTask<String, Integer, JSONObject> {
    HttpURLConnection urlConnection;
    String url;
    String method;
    String payload = null;
    AsyncResponse delegate = null;
    int requestCode;

public FetchData(String url, String method) {
    this(url, method, null);
}

public FetchData(String url, String method, JSONObject payload) {
    this.url = url;
    this.method = method;
    if(payload!=null){
         this.payload = payload.toString();
    }
}

//You can set AsyncResponse and RequestCode in constructor also.
public FetchData setListener(AsyncResponse asyncResponse, int requestCode){
    this.delegate = asyncResponse;
    this.requestCode = requestCode;
    return this;
}

@Override
protected JSONObject doInBackground(String... args) {
    ....
}

@Override
protected void onPostExecute(JSONObject result) {
    super.onPostExecute(result);
        if(delegate!=null){        
            //post result with given requestCode
            this.delegate.processFinish(result, requestCode);
        }
    }
}


public class AsyncTasks extends AppCompatActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_async_tasks);

    // Make first call with request code as 1. Use anonym callBack implementation
    new FetchData("<url 1>", "GET").setListener(new AsyncResponse () {
            @Override
            public void processFinish(JSONObject sb, int requestCode) {
                //perform task on 1st call finish
            }
        }, 1).executeOnExecutor(THREAD_POOL_EXECUTOR);

    // Make second call with request code as 2
    new FetchData("<url 2>", "GET").setListener(new AsyncResponse () {
            @Override
            public void processFinish(JSONObject sb, int requestCode) {
                //perform task on 2st call finish
            }
        }, 2).executeOnExecutor(THREAD_POOL_EXECUTOR);

    // Make as many call to FetchData and implement an anonym AsyncResponse each time

}