避免 onActivityResult 和 onRequestPermissionsResult 烦恼requestCode的问题,帮助快速开发~~
在子项目中的 build.gradle 文件中添加
dependencies {
implementation'vip.ruoyun.helper:avoid-onresult-helper:1.0.4'
}Intentintent = newIntent();
AvoidOnResultHelper.startActivityForResult(this, intent, newAvoidOnResultHelper.ActivityCallback() {
@OverridepublicvoidonActivityResult(intresultCode, Intentdata) {
//接收数据//Log.d("MainActivity", "resultCode:" + resultCode);//Log.d("MainActivity", "Intent data:" + data.getStringExtra("text"));
}
});在新的Activity中,通过下面的方法来快速关闭界面并传回值。
AvoidOnResultHelper.finishWithResult(activity, Activity.RESULT_OK, intent);
AvoidOnResultHelper.finishWithResult(activity, Activity.RESULT_OK, bundle);
//相当于//Intent intent = new Intent();//intent.putExtra("text", "返回数据");//setResult(Activity.RESULT_OK, intent);//finish();String[] permissions = {};
AvoidOnResultHelper.requestPermissions(this, permissions, newAvoidOnResultHelper.PermissionsCallBack() {
@OverridepublicvoidonRequestPermissionsResult(@NonNullString[] permissions, @NonNullint[] grantResults) {
}
});如果在使用的过程中,发现 RequestCode 和原有的值发生冲突,那么可以通过下面的方法,进行设置 默认值为:
- start:65000
- end:65535
AvoidOnResultHelper.setRequestCodeRange(65000, 65535);监听当前 activity 的生命周期.
publicinterfaceLifecycleListener {
voidonStart();//开始voidonStop();//结束voidonDestroy();//销毁
}LifecycleListenerWrapper 是此接口的空实现.
使用
//添加监听事件LifecycleListenerlifecycleListener = newLifecycleListener.LifecycleListenerWrapper() {
@OverridepublicvoidonStart() {
}
};
//添加监听事件AvoidOnResultHelper.addLifecycleListener(this, lifecycleListener);
//粘性通知,当第一次添加的时候,就执行相应的回调方法AvoidOnResultHelper.addLifecycleListener(this, lifecycleListener, true);可选操作
//移除监听事件,默认可以不用移除lifecycleListener,除非在当前界面存在时候,想要不让某些类监听,那么可以手动进行移除(removeLifecycleListener)AvoidOnResultHelper.removeLifecycleListener(this, lifecycleListener);当在一个界面中打开另一个界面的时候,如果想要新界面传回值,那么就需要执行下面的方法
//定义 requestCode startActivityForResult(Intentintent, intrequestCode);然后在要接受数据的界面添加如下方法
@OverridepublicvoidonActivityResult(intrequestCode, intresultCode, Intentdata) {
super.onActivityResult(requestCode, resultCode, data);
//判断 requestCode
}比如打开相册,要写如下的代码。
privatefinalstaticintREQUEST_CODE = 100;
privatevoidchoosePhoto(){
//省略权限检测和申请
...
IntentintentToPickPic = newIntent(Intent.ACTION_PICK, null);
// 如果限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型" 所有类型则写 "image/*"intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg");
startActivityForResult(intentToPickPic, REQUEST_CODE);
}
//当拍摄照片完成时会回调到onActivityResult 在这里处理照片的裁剪@OverridepublicvoidonActivityResult(intrequestCode, intresultCode, Intentdata) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
caseREQUEST_CODE: {
//处理图片逻辑
...
break;
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}所以,我们想要做这些操作的时候,要写至少 18 行代码 和定义一个 code 码。如果快速开的话,这些操作还挺烦的。 那么我们应该怎么来进行简单呢?
当阅读 glide 源码的时候,发现它可以监听声明周期,让图片随着界面的声明周期进行下载和展示,那么它是如何来解决这个问题的呢?
它是在 调用 with 的时候,传入的上下文,来监听界面的事件。
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);finalFragmentManagerImplmFragments = newFragmentManagerImpl();
protectedvoidonCreate(@NullableBundlesavedInstanceState) {
this.mFragments.attachHost((Fragment)null);
super.onCreate(savedInstanceState);
...//省略不必要的代码this.mFragments.dispatchCreate();
}
protectedvoidonStart() {
super.onStart();
...//省略不必要的代码this.mFragments.noteStateNotSaved();
this.mFragments.execPendingActions();
this.mFragments.dispatchStart();
}
protectedvoidonStop() {
super.onStop();
...//省略不必要的代码this.mFragments.dispatchStop();
}
protectedvoidonPause() {
super.onPause();
...//省略不必要的代码this.mFragments.dispatchPause();
}
protectedvoidonDestroy() {
super.onDestroy();
...//省略不必要的代码this.mFragments.dispatchDestroy();
}
publicvoidonLowMemory() {
super.onLowMemory();
this.mFragments.dispatchLowMemory();
}
protectedvoidonActivityResult(intrequestCode, intresultCode, Intentdata) {
...//省略不必要的代码FragmenttargetFragment = mFragments.findFragmentByWho(who);
targetFragment.onActivityResult(requestCode & 0xffff, resultCode, data);
...//省略不必要的代码
}
publicvoidonRequestPermissionsResult(intrequestCode, @NonNullString[] permissions,
@NonNullint[] grantResults) {
...//省略不必要的代码finalList<Fragment> activeFragments =
mFragments.getActiveFragments(newArrayList<Fragment>(activeFragmentsCount));
Fragmentfrag = activeFragments.get(index);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for index: 0x"
+ Integer.toHexString(requestCode));
} else {
frag.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults);
}
...//省略不必要的代码
}
}我们在来看 FragmentManagerImpl 的源码,就知道 FragmentActivity 的声明周期方法在执行的时候,都会执行包含的 fragment 的声明周期方法。
publicvoiddispatchCreate() {
mStateSaved = false;
moveToState(Fragment.CREATED, false);
}
publicvoiddispatchActivityCreated() {
mStateSaved = false;
moveToState(Fragment.ACTIVITY_CREATED, false);
}
publicvoiddispatchStart() {
mStateSaved = false;
moveToState(Fragment.STARTED, false);
}
voidmoveToState(intnewState, booleanalways) {
moveToState(newState, 0, 0, always);
}
voidmoveToState(intnewState, inttransit, inttransitStyle, booleanalways) {
...//省略不必要的代码if (mActive != null) {
booleanloadersRunning = false;
for (inti=0; i<mActive.size(); i++) {
Fragmentf = mActive.get(i);
if (f != null) {
moveToState(f, newState, transit, transitStyle, false);// 执行声明周期方法
...//省略不必要的代码
}
}
...//省略不必要的代码
}
}
voidmoveToState(Fragmentf, intnewState, inttransit, inttransitionStyle,
booleankeepActive) {
...//省略不必要的代码switch (f.mState) {
caseFragment.INITIALIZING:
...//省略不必要的代码f.onAttach(mActivity);
...//省略不必要的代码if (f.mFromLayout) {
...//省略不必要的代码if (f.mView != null) {
...//省略不必要的代码f.onViewCreated(f.mView, f.mSavedFragmentState);
} else {
f.mInnerView = null;
}
}
caseFragment.CREATED:
...//省略不必要的代码f.onViewCreated(f.mView, f.mSavedFragmentState);
...//省略不必要的代码caseFragment.ACTIVITY_CREATED:
caseFragment.STOPPED:
...//省略不必要的代码f.performStart();
caseFragment.STARTED:
...//省略不必要的代码f.performResume();
}
} elseif (f.mState > newState) {
switch (f.mState) {
caseFragment.RESUMED:
...//省略不必要的代码f.performPause();
caseFragment.STARTED:
f.performStop();
caseFragment.STOPPED:
f.performReallyStop();
caseFragment.ACTIVITY_CREATED:
f.performDestroyView();
caseFragment.CREATED:
...//省略不必要的代码
}
}
f.mState = newState;
}这里,我们就可以 创建一个 没有界面的 fragment 添加到 activity 中,就可以完美监听界面的声明周期 和回调方法。到此原理讲解结束。
比如我们现在 很多第三方的库,glide 、Android Architecture Component 等等这些库都是使用这些原理。