有没有办法重用构建器代码进行改造

bir*_*rdy 21 java android retrofit

我正在使用Retrofit,在每项任务中我都必须做这样的事情:

public class MyTask extends AsyncTask<String, String, String> {

    private void someMethod() {
        final RestAdapter restAdapter = new RestAdapter.Builder()
            .setServer("http://10.0.2.2:8080")
            .build();
        final MyTaskService apiManager = restAdapter.create(MyTaskService.class);
    }

    // ...

}
Run Code Online (Sandbox Code Playgroud)

使这段代码干的好方法是什么?

Jak*_*ton 45

无论是RestAdapter和您的服务生成的实例(MyTaskService在这种情况下)是非常昂贵的物品,应作为单身.

这意味着您应该只调用restAdapter.create一次并在MyTaskService每次需要交互时重复使用相同的实例.

我不能强调这一点.

您可以使用常规单例模式,以确保在任何地方只使用这些对象的单个实例.依赖注入框架也可用于管理这些实例,但如果您尚未使用它,则会有点矫枉过正.

  • @ jake-wharton这对于Retrofit 2仍然有效吗? (11认同)
  • @Eugene是的它仍然很昂贵.您可能不会注意到其中的100个.但是如果你将这些物体与一些日常丢弃的物体进行比较,你会发现它的成本更高,数百到数百万.该课程也被设计为可重复使用.它是线程安全的,延迟加载和缓存,并且在优化重用案例方面进行了大量工作.这就像每天买新袜子而不是洗它们.你可以逃脱它,但它没有意义. (2认同)

Gau*_*tam 45

正如杰克所说,你应该使用单例模式,以确保始终使用相同的实例.

这是一个例子:

public class ApiManager {

    public interface GitHubService {

        @GET("/users/{user}/repos")
        List<Repo> listRepos(@Path("user") String user);

    }

    private static final String API_URL = "https://api.github.com";

    private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
        .setEndpoint(API_URL)
        .setLogLevel(LogLevel.FULL)
        .build();

    private static final GitHubService GIT_HUB_SERVICE = REST_ADAPTER.create(GitHubService.class);

    public static GitHubService getService() {
        return GIT_HUB_SERVICE;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在此示例中使用此服务,如下所示:

ApiManager.getService().listRepos(...);
Run Code Online (Sandbox Code Playgroud)


Car*_*les 5

首先,您声明您的父类具有所有常见行为

public abstract class MyAbstractTask extends AsyncTask<String, String, String> {

 protected void someMethod() { //note that i change private to protected
  final RestAdapter restAdapter = new RestAdapter.Builder().setServer("http://10.0.2.2:8080").build();
  final MyTaskService apiManager = restAdapter.create(MyTaskService.class);
 }

}
Run Code Online (Sandbox Code Playgroud)

然后,你将它扩展到每个任务

public   class MyTask extends MyAbstractTask {

 //your someMethod() is available from everywhere in your class

}

public  class MyOtherTask extends MyAbstractTask {

 //your someMethod() is available from everywhere in your class

}
Run Code Online (Sandbox Code Playgroud)

但我不知道你在哪里使用restAdapter和apiManager,如果每个任务实际上需要创建一次,因为你可能可以在这些任务之外创建它.

如果你在外面创建它们,然后你需要在你的任务中使用某些东西,那么记住Dependency_injection模式也是很好的 .


此外,您应该避免在类中使用硬编码值,例如 http://10.0.2.2:8080

您应该至少使用a final static final String server= "http://10.0.2.2:8080"然后使用它,或者更好地使用最内层类中的setter或构造函数,并从activity或main控制器设置tha值.