Android - 如何在Class中使用AsyncTasks

时间:2013-02-15 08:49:25

标签: java android android-asynctask httprequest

我正在构建一个与API通信的应用。我将所有API通信代码和数据处理放在一个API class中,这样每次我想使用API​​时,我都有一个所有逻辑所在的中心位置。

对于HTTPRequests,强烈建议使用AsyncTasks。如示例所示,您可以通过派生整个类来创建AsyncTask

我的类包含由于HTTP调用而需要异步的函数。其他没有。

我的问题:我是从AsyncTask派生出我的整个API类,还是应该在普通和异步部分中更多地划分我的API类?

3 个答案:

答案 0 :(得分:2)

使用两种方法创建一个接口,一种不在其他线程上执行,另一种不执行。使异步方法接受回调对象,以便在完成后得到通知。 例如:

public interface MyAPI {
 //--this method runs an AsyncTask and calls supplied Callback object's methods when done
 public void fetchRemoteData(String input, Callback c);

 //--this method just processes input string locally and returns it
 public String doStuff(String input);
}

public interface Callback{
  public void onDone(int doneWhatCode, String result);
}

实现:

public class MyWebAPI implements MyAPI{
  @Override
  public void fetchRemoteData(String input, final Callback c){
        AsyncTask<String,Void,String> task = new AsyncTask<String,Void,String>(){

            @Override
            protected String doInBackground(String... strings) {
                String i = strings[0];

                //---connect, fetch data ----
                String result = "result";

                return result;
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                c.onDone(1,s);
            }
        };

      task.execute("new Input url");
    }

  @Override
  public String doStuff(String input){
    return input.replace("i","o");
  }
}

让这些接口公开您的API。通过这种方式,您可以将所有内容保持在一起,并将实际实现分开以供将来更改。

答案 1 :(得分:0)

这里的要点是“你不能使用这个类形成一个UI线程”,然后你创建一个AsyncTask。如果您有服务并想从那里调用一些API方法怎么办?您无法从服务线程调用AsyncTask 当我想从UI调用它时,我会保留这个类,并将它包装在AsyncTask中。

编辑:这是将现有功能包装到AsyncTask中的示例:

private class GetAuthorisationUrlTask extends AsyncTask<String, Void, String>
{
    private OAuthBuilder oAuthBuilder;
    private GetAuthorisationUrlTaskCallback callback;

    public GetAuthorisationUrlTask(Context context, OAuthBuilder oAuthBuilder, GetAuthorisationUrlTaskCallback callback)
    {
        this.oAuthBuilder = oAuthBuilder;
        this.callback = callback;
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            Log.i(TAG, "Getting authorization url...");
            return oAuthBuilder.getAuthorizationUrl();
        }
        catch (Exception e)
        {
            Log.e(TAG, "Unable to get OAuth authorization url: " + e, e);
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result)
    {
        Log.i(TAG, "Authorisation url: " + result);
        if (result == null)
            Toast.makeText(getApplicationContext(), "Error getting authorization url.", Toast.LENGTH_SHORT).show();
        else
            callback.urlCreated(result);
    }

    static interface GetAuthorisationUrlTaskCallback
    {
        void urlCreated(String url);
    }
}

现在,您可以调用AsyncTask并在结果准备就绪时获得回调。

GetAuthorisationUrlTask getAuthorisationUrlTask = new GetAuthorisationUrlTask(this,
        new GetAuthorisationUrlTaskCallback()
        {
            @Override
            public void urlCreated(String url)
            {
                webview.loadUrl(url);
            }
        });
getAuthorisationUrlTask.execute();

我知道有很多样板代码,但它将您的UI完全与业务类的逻辑分开。它在这里只执行一项任务,但是将其扩展为更通用,并且在不引入新类的情况下执行更多操作很容易。

答案 2 :(得分:0)

那对你有好处。你可以让1 AsyncTask处理所有事情并进行更新等等。但是如果有很多不同的请求并没有直接相关,我会将它们分开。一个好的方法可能是考虑用例,并根据它分成不同的AsyncTasks

举一个基于用例的方法的例子:

  • 主要Activity首先启动AsyncTask进行初始化。
  • 用户点击登录/或启动其他长时间运行操作 - &gt;开始第二个AsyncTask

然后在这两种情况下,你仍然会有旧课程,但AsyncTasks会调用旧课程中实现的api。