Ric*_*ick 21 java android retrofit okhttp retrofit2
如何LoginActivity从拦截器(非活动类)开始?我已经尝试过Interceptor下面的代码()但不适合我.
拦截器
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + auth_token_string)
.build();
Response response = chain.proceed(newRequest);
Log.d("MyApp", "Code : "+response.code());
if (response.code() == 401){
Intent intent = new Intent(SplashActivity.getContextOfApplication(), LoginActivity.class);
startActivity(intent);
finish(); //Not working
return response;
}
return chain.proceed(newRequest);
}
}).build();
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的当前解决方案,有没有比这更好的解决方案?该解决方案必须在每次api呼叫时保持重复.
主要活动
call.enqueue(new Callback<Token>() {
@Override
public void onResponse(Call<Token> call, Response<Token> response) {
if(response.isSuccessful())
{
//success
}
else
{
Intent intent = new Intent(MainActivity.this.getApplicationContext(), LoginActivity.class);
startActivity(intent);
finish();
}
}
@Override
public void onFailure(Call<Token> call, Throwable t) {
}
});
Run Code Online (Sandbox Code Playgroud)
考虑引入retrofit2.Callback接口的自定义实现,例如BaseCallback:
public abstract class BaseCallback<T> implements Callback<T> {
private final Context context;
public BaseCallback(Context context) {
this.context = context;
}
@Override
public void onResponse(Call<T> call, Response<T> response) {
if (response.code() == 401) {
// launch login activity using `this.context`
} else {
onSuccess(response.body());
}
}
@Override
public void onFailure(Call<T> call, Throwable t) {
}
abstract void onSuccess(T response);
}
Run Code Online (Sandbox Code Playgroud)
现在,从主叫方的网站,你应该改变new Callback<Token>有new BaseCallback<Token>:
call.enqueue(new BaseCallback<Token>(context) {
@Override
void onSuccess(Token response) {
// do something with token
}
});
Run Code Online (Sandbox Code Playgroud)
虽然,这种方法不符合您的以下声明:
所以我不必为每个api调用再次重复相同的代码
尽管如此,我无法想出更好的方法.
就个人而言,我建议在这里使用事件总线模式。您可以使用greenrobot实现或任何您想要的方法,因为它更多是关于体系结构方法而不是具体实现。
创建事件模型
public class UnauthorizedEvent {
private static final UnauthorizedEvent INSTANCE = new UnauthorizedEvent();
public static UnauthorizedEvent instance() {
return INSTANCE;
}
private UnauthorizedEvent() {
}
}
Run Code Online (Sandbox Code Playgroud)实施自定义Interceptor,以处理有关未经授权的需求的事件
class UnauthorizedInterceptor implements Interceptor {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (response.code() == 401) {
EventBus.getDefault().post(UnauthorizedEvent.instance());
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)创建BaseActivity处理的类UnauthorizedEvent
public class BaseActivity extends Activity {
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Subscribe
public final void onUnauthorizedEvent(UnauthorizedEvent e) {
handleUnauthorizedEvent();
}
protected void handleUnauthorizedEvent() {
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
}
}
Run Code Online (Sandbox Code Playgroud)阻止LoginActivity从LoginActivity
public class LoginActivty extends BaseActivity {
@Override
protected void handleUnauthorizedEvent() {
//Don't handle unauthorized event
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是不在BaseActivity此处扩展。
注册您的拦截器
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new UnauthorizedInterceptor())
.build();
Run Code Online (Sandbox Code Playgroud)优点:
handleUnauthorizedEventCallback代替BaseCallback)缺点:
另外,请注意,此示例未涵盖多线程问题。它解决了您处理未经授权的请求的问题。因此,如果两个请求收到401,则有可能LoginActivity启动2个实例。
这就是拦截器在全球范围内处理 401 的方式
public class ResponseHeaderInterceptor implements Interceptor {
private final Context context;
public ResponseHeaderInterceptor(Context context) {
this.context = context;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if(response.code() == 401){
SharedPreferences pref = context.getSharedPreferences(Constants.PREFERENCES, 0);
String userName = pref.getString("key_user_email", "");
//clear shared preferences
pref.edit().clear().apply();
Bundle params = new Bundle();
params.putString("user", userName);
FirebaseAnalytics.getInstance(context).logEvent(Constants.USER_UNAUTHORIZED_EVENT, params);
Intent intent = new Intent(this.context, IntroActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.context.startActivity(intent);
}
return response;
}
Run Code Online (Sandbox Code Playgroud)
}
添加retrofit的okhttp客户端
var okHttpClient: OkHttpClient = OkHttpClient()
.newBuilder()
.addInterceptor(ResponseHeaderInterceptor(MyApplication.getMyApplicationContext()))//Header interceptor for logging network responses
.build()
private var retrofit: Retrofit? = null
val client: Retrofit?
get() {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BuildConfig.SERVER)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3150 次 |
| 最近记录: |