最近在移植项目代码,相当与从4.4移植到7.1上,中间项目还有6.0的版本。
从4.4到6.0没有任何问题,但是无论是4.4到7.1上还会6.0到7.1上都会出现ANR:
空指针:mSelectionListenerCallback为空。
构造顺序:
- 创建Fragment
FragmentTransaction transaction = getFragmentManager().beginTransaction();
FolderFragment foldfragment = new FolderFragment();
foldfragment.setArguments(bundle);
String name = makeFragmentName(R.id.pager, CATEGORY);
transaction.add(R.id.pager, foldfragment, name);
transaction.addToBackStack(name);
transaction.commit();
此时R.id.pager的控件应该是foldfragment,在4.4和6.0上确实是,而在7.0上就变为categoryfragment(吃个蒙逼果)
如果是folderfragment自然没有问题,监听了各类操作MenuExecutor.FileSelectionListener:
public class FolderFragment extends Fragment implements SelectionManager.SelectionListener,
MenuExecutor.FileSelectionListener {...}
如果是categoryfragment就不对了,啥操作也没有,不报空指针倒有鬼了:
public class CategoryFragment extends Fragment implements OnItemClickListener {...}
- 正常操作下,folderfragment
通过构造函数到onCreate()里的部分代码如下:
mSelectionManager = new SelectionManager();
mSelectionManager.setSelectionListener(this);
mActionModeHandler = new ActionModeHandler(getActivity(), mSelectionManager);
mActionModeHandler.setActionModeListener(new ActionModeListener() {
@Override
public boolean onActionItemClicked(MenuItem item) {
Log.d(TAG,"onActionItemClicked");
return true;
}
});
ActionModeHandler的构造函数:
public ActionModeHandler(Activity activity, SelectionManager selectionManager) {
mActivity = activity;
mSelectionManager = selectionManager;
mMenuExecutor = new MenuExecutor(activity, mSelectionManager);
}
MenuExecutor的构造函数:
public MenuExecutor(Activity activity, SelectionManager selectionManager) {
mActivity = activity;
mFileOperationCallback = (FileOperationListener) activity;
if ((Fragment)mActivity.getFragmentManager().findFragmentById(R.id.pager) instanceof FolderFragment) {
mSelectionListenerCallback =
(FileSelectionListener)mActivity.getFragmentManager().findFragmentById(R.id.pager);
}
mSelectionManager = selectionManager;
}
注意到如果是FolderFragment就会注册mSelectionListenerCallback。
3. 异常操作下,categoryfragment
如上流程categoryfragment的构造函数啥也没有,所以mSelectionListenerCallback就为空拉。
然后,我就一通乱改,蒙逼无数次,浪费了至少三天,最后大神同时同步了6.0的代码就好了…
你以为我会那么傻?移植最简单的就是copy,我就是copy过来编译的,为什么他行我就不行?肯定有猫腻。
果不其然,他加了一句
android:targetSdkVersion="19"
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
就是这么神奇,本来很久没写blog了,这次忍不住写来吐槽。
资料太多:https://blog.csdn.net/manoel/article/details/40046887
Android API Level对应Android版本一览表:https://blog.csdn.net/chenmiaoqin950606/article/details/78959683
最后告诫各位程序员,这种问题真的只能听天由命,我宁愿开发也不要移植。