Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该使用一个全局改型实例还是为Android中的每个请求创建一个?_Java_Android_Retrofit2_Okhttp3 - Fatal编程技术网

Java 我应该使用一个全局改型实例还是为Android中的每个请求创建一个?

Java 我应该使用一个全局改型实例还是为Android中的每个请求创建一个?,java,android,retrofit2,okhttp3,Java,Android,Retrofit2,Okhttp3,嗯,我现在迷上了改装。。。首先,我编写了一个Singleton helper类,该类保存由改造实例创建的服务实例。获取服务并发出HTTP请求非常方便,但是我发现我无法从SharedReferences获取访问令牌,因为helper实例是静态的。因为我使用Authenticator接口来处理身份验证,所以在发出请求时不可能传递访问令牌。我试图扩展应用程序类并将应用程序实例保存在静态字段中,但Android Studio给了我一个警告(不要将Android上下文类放置在静态字段中;这是内存泄漏(也会

嗯,我现在迷上了改装。。。首先,我编写了一个Singleton helper类,该类保存由改造实例创建的服务实例。获取服务并发出HTTP请求非常方便,但是我发现我无法从SharedReferences获取访问令牌,因为helper实例是静态的。因为我使用Authenticator接口来处理身份验证,所以在发出请求时不可能传递访问令牌。我试图扩展应用程序类并将应用程序实例保存在静态字段中,但Android Studio给了我一个警告(
不要将Android上下文类放置在静态字段中;这是内存泄漏(也会中断即时运行)

所以现在我有了另一个选择:编写一个静态helper方法,对于每个请求,它接受访问令牌,构建一个改造实例,创建一个服务实例并发出请求。现在我弄不清楚这是否是一种最佳做法。重用一个服务实例和为每个请求创建服务有什么区别


注:上面的
service
一词指的是由
someReformation.create(someServiceInterface.class)
创建的服务实例,而不是
android.app.service

我还建议您只使用单例方法,因为从设计角度来看也是很好的

如果您创建多个服务实例,每个实例都可能具有不同的网络属性,如readTimeout、writeTimeout、响应日志属性等,或者您必须将它们全部设置为一个属性,如果我们在团队中工作,这可能会让您非常头痛

我面临的一个用户案例是,在稍后的某个时间点,您的后端团队在每个请求(如设备os版本)上添加额外的头参数,然后您必须将此属性添加到所有改装客户端,这将是一个难题

下面是我的代码片段,我是如何处理标题的

public static Retrofit getRestAdapter(final HashMap<String, String> requestHeaderMap) {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request.Builder builder = chain.request().newBuilder();
                    Set<Map.Entry<String, String>> entrySet = requestHeaderMap.entrySet();
                    for (Map.Entry<String, String> entry : entrySet) {
                        if (entry.getValue().isEmpty())
                            builder.removeHeader(entry.getKey());
                        else
                            builder.addHeader(entry.getKey(), entry.getValue());
                    }

                    Request request = builder.build();
                    return chain.proceed(request);
                }


            }).build();

    return new Retrofit.Builder()
            .baseUrl(Constants.BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}
公共静态改装getRestAdapter(最终HashMap requestHeaderMap){
HttpLoggingInterceptor拦截器=新的HttpLoggingInterceptor();
拦截器.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient客户端=新建OkHttpClient.Builder()
.addInterceptor(拦截器)
.addInterceptor(重写缓存控制拦截器)
.addNetworkInterceptor(新的Interceptor(){
@凌驾
公共响应拦截(链)引发IOException{
Request.Builder=chain.Request().newBuilder();
Set entrySet=requestHeaderMap.entrySet();
for(Map.Entry:entrySet){
if(entry.getValue().isEmpty())
removeHeader(entry.getKey());
其他的
builder.addHeader(entry.getKey(),entry.getValue());
}
Request=builder.build();
返回链。继续(请求);
}
}).build();
返回新的改装.Builder()
.baseUrl(常量.BASE\u URL)
.客户(客户)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
requestHeaderMap的is实例是全局实例,使用可观察模式将数据推入其中


我希望这能帮助您做出决定。

有趣的是,在我的项目中,它没有给出内存泄漏的警告。但无论如何,这只是一个警告。保持对应用程序的静态引用没有错。我这里有一个答案。所以我的建议是只使用单个应用程序,不要担心这个警告。@Budius实际上我还想知道重用由
someRefundation.create(xxx.class)
创建的单个实例与每次请求都这样做之间的区别。我从来没有深入研究过,但是这个实例似乎是在控制/保存线程、回调、拦截器,所以您可能不应该每次都创建一个新的实例。