3

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

问题是,HTTPRequests强烈建议使用AsyncTasks. 如示例中所示,您AsyncTask通过派生整个类来创建一个。

我的课程包含由于 HTTP 调用而需要异步的函数。其他的不要。

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

4

3 回答 3

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。通过这种方式,您可以将所有内容放在一起,也可以将实际实现分开以备将来更改。

于 2013-02-15T09:02:09.027 回答
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 与您的业务类的逻辑完全分开。它在这里只完成一项任务,但将其扩展为更通用并在不引入新类的情况下做更多事情很容易。

于 2013-02-15T09:01:06.860 回答
0

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

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

  • MainActivity首先启动AsyncTask以进行初始化。
  • 用户单击登录/或开始其他长时间运行的操作 --> 开始第二次AsyncTask

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

于 2013-02-15T09:03:13.057 回答