【问题标题】:Where to attach the reference to a Retrofit adapter in Android?在哪里附加对 Android 中改造适配器的引用?
【发布时间】:2014-08-13 19:59:55
【问题描述】:

我引用了这篇帖子 Where to keep Retrofit Adapter in Android App?,但由于 stackoverflow 的限制,我不能在那里发表评论 [感谢 stackoverflow 将新用户像孩子一样对待]。

使用 Android 时,Retrofit RestAdpater 去哪儿了?谁能详细说明@Jake Wharton 对上述帖子的回答。

当我将 RestAdapter 放置在我的 Activity 中时,它可能会在 Activity 被销毁时被 GCed,因此 Singleton 失去了它的引用并且需要在下一次重新创建(我假设)。

此外,我为测试所做的第一件事就是这个,Android 告诉我我不能在主线程上执行网络请求。我知道我不能这样做,但我认为 Retrofit 会自动为我创建一个单独的线程。

我是否需要创建一个 AsyncTask 来托管 RestAdapter?或者这对 Android 有什么作用?适配器最好在哪里实例化?附上改造参考的推荐点是什么?

【问题讨论】:

    标签: android retrofit


    【解决方案1】:

    所以@JakeWharton 说的是 RestAdapter 和 api 接口实例应该创建一次。你如何实现这一点几乎是一个实现细节。

    您可以直接创建一个类,该类将为您的 RestAdapter 保存一个实例。您将负责只创建该类的单个实例。您可能希望在 Application 类中保留对此类的引用。你也可以使用Singleton pattern

    这是一个帮助您入门的小课程。我从以前的帖子中获取了这个,你可以看到 here

    public class RestApiDispencer {
        private Map<String, Object> restApiInstances = new HashMap<String, Object>();
        private RestAdapter restAdapter;
    
        public RestApiDispencer(RestAdapter restAdapter) {
            this.restAdapter = restAdapter;
        }
    
        public <T> T getRestApi(Class<T> clazz) {
                T client = null;
                if ((client = (T) restApiInstances.get(clazz.getCanonicalName())) != null) {
                    return client;
                }
                client = restAdapter.create(clazz);
                restApiInstances.put(clazz.getCanonicalName(), client);
                return client;
        }
    }
    

    如果您熟悉依赖注入,那将是另一种方法。我个人更喜欢使用依赖注入来隐藏实现细节。

    将 RestAdapter 直接创建到您的 Activity 中并不是您想要的方式。相反,在您的活动中,您希望从上面获取对此 RestApiDispencer 类的引用,并通过像这样提供它的类,让它返回您选择的其余 api 的实例。

    MyClassApi myClassApi = restApiDispencer.getRestApi(MyClassApi.class);
    

    还有其他方法可以实现这一点,但正如我所说,由您决定哪种实现最适合您的需求。

    至于 Retrofit 在单独的线程上执行请求,是的,但您需要相应地创建您的 Api 接口。

    @GET(/some/rest/api/path)
    Response getApiData() // Synchronous declaration as the Response is returned from the method.
    
    @GET(/some/rest/api/path)
    void getApiData(Callback<Response> callback); // Asynchronous as the Response is delivered in the callback.
    
    @GET(/some/rest/api/path)
    Observable<Response> getApiData(); // Asynchronous again but you'll need to read up on rx-java before using this. 
    

    阅读 rx-java here

    因此,如果您决定使用异步签名来创建您的 REST API,那么您在调用接口时就不必担心线程问题。如果您使用同步签名,那么一切都取决于您。

    【讨论】:

    • 感谢您的详细回答。您是在说“您可能希望在 Application 类中保留对此类的引用。您也可以使用 Singleton 模式来解决这个问题”。应用类引用清楚了,但是Android中的Singleton和GC呢? Singleton 是否会阻止自己在没有引用的情况下被垃圾收集?示例:按照建议,我使用单例并从 Activity 实例化它,但我没有在任何地方保留引用。 Singleton 中的静态代码块在连续访问时保持实例化。但是 GC 呢?
    • 我想添加一个链接:portabledroid.wordpress.com/2012/05/04/singletons-in-android - 关于这个主题有多少意见以及它们之间的差异是多么令人困惑。
    • 如果 Singleton 讨论的是一个具有“静态”成员的类,那么它不会被垃圾收集,因为静态成员不是堆的一部分。这意味着在 Android 世界中,相同的 Singleton 实例将在“进程”期间可用。如果您的进程很可能会消失,那么您的单例将不得不重新创建。至于你的例子,不会因为我刚才提到的同样原因而被垃圾收集。
    猜你喜欢
    • 2018-03-16
    • 2021-02-06
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    相关资源
    最近更新 更多