我正在使用HTC Desire(Gingerbread 2.3.7)和Google Nexus 7(Jelly Bean 4.3)开发我的Android项目。我需要将一些数据从MainActivity发送到InfoActivity,所以我使用了一个intent。在此InfoActivity中,我还在操作栏中有一个菜单项来刷新信息。
在InfoActivity中,我向用户显示数据。但这不是问题,问题在于菜单。请查看以下代码:
public class ShowInfoActivity extends ActionBarActivity {
private MenuItem menuItem = null;
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
new OneTask().execute(...);
// ...
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
case R.id.refresh:
menuItem = item;
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private class OneTask extends AsyncTask<Object, Void, String> {
// ...
@Override
protected void onPreExecute() {
MenuItemCompat.setActionView(menuItem,
R.layout.actionbar_indeterminate_progress);
MenuItemCompat.expandActionView(menuItem);
}
// ...
@Override
protected void onPostExecute(String result) {
MenuItemCompat.collapseActionView(menuItem);
MenuItemCompat.setActionView(menuItem, null);
}
}
显然,第一次执行时,menuItem = null,所以必须崩溃。令人难以置信的是,在HTC中它运行良好,但在Nexus中它显然崩溃了。为什么设备之间会有所不同?
PS:我已经解决了,但我想知道为什么会这样......答案 0 :(得分:1)
如有疑问,请务必查看源代码。如果您查看MenuItemCompat.java,您会发现它基于API级别进行切换,如下所示:
static final MenuVersionImpl IMPL;
static {
final int version = android.os.Build.VERSION.SDK_INT;
if (version >= 14) {
IMPL = new IcsMenuVersionImpl();
} else if (version >= 11) {
IMPL = new HoneycombMenuVersionImpl();
} else {
IMPL = new BaseMenuVersionImpl();
}
}
基本实现的基本setActionView方法(用于2.3设备)只返回MenuItem,因此它不会抛出异常:
@Override
public MenuItem setActionView(MenuItem item, View view) {
return item;
}
另一方面,HoneycombMenuVersionImpl委托另一个班级:
@Override
public boolean setShowAsAction(MenuItem item, int actionEnum) {
MenuItemCompatHoneycomb.setShowAsAction(item, actionEnum);
return true;
}
委托类尝试在MenuItem上调用实际方法,这将引发异常:
public static void setShowAsAction(MenuItem item, int actionEnum) {
item.setShowAsAction(actionEnum);
}
在这个特定示例中,检查源代码可以回答您的问题,并向您展示处理不同Android版本之间兼容性的可靠策略。
答案 1 :(得分:0)
setActionView()/ collapseActionView()是Android 4中的本机函数...传递null MenuItem肯定会不受欢迎。
在Android 2.3设备上,兼容性库(android.support.v4)拥有自己的setActionView()/ collapseActionView()内部实现,这些实现可能对错误输入更具弹性。