我有这项活动。在内部活动我有3个asynctask,我需要其中一个在onCreate方法中执行。我想按照本网站http://www.androidhive.info/2013/11/android-working-with-action-bar/上的教程实现一个刷新按钮(几乎在最后),但问题是我希望操作栏刷新按钮执行asynctask,这是首先在onCreate方法中调用的。活动示例:
package info.androidhive.actionbar;
import info.androidhive.actionbar.model.SpinnerNavItem;
import info.androidhive.info.actionbar.adapter.TitleNavigationAdapter;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.SearchView;
public class MainActivity extends Activity implements
ActionBar.OnNavigationListener {
// action bar
private ActionBar actionBar;
// Refresh menu item
private MenuItem refreshMenuItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new SyncData.execute(); //this is example of my implementation I call my asynctask here
actionBar = getActionBar();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
....
}
/**
* On selecting action bar icons
* */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Take appropriate action for each action item click
switch (item.getItemId()) {
...
case R.id.action_refresh:
// refresh
refreshMenuItem = item;
// load the data from server
new SyncData().execute();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Async task to load the data from server
* **/
private class SyncData extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
// set the progress bar view
refreshMenuItem.setActionView(R.layout.action_progressbar);
refreshMenuItem.expandActionView();
}
@Override
protected String doInBackground(String... params) {
// not making real request in this demo
// for now we use a timer to wait for sometime
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
refreshMenuItem.collapseActionView();
// remove the progress bar view
refreshMenuItem.setActionView(null);
}
};
}
所以按照本教程中的
行refreshMenuItem.setActionView(R.layout.action_progressbar);
我坚持使用对refreshMenuItem的null引用。有解决方法吗?
答案 0 :(得分:1)
是的,有。当您在AsyncTask
中运行onCreate(..)
时,您的MenuItem
尚未初始化 - 因为当用户按下相应的按钮时,由于某些奇怪的原因,它会被初始化,这发生在{{1}内}}。这就是你获得onOptionsItemSelected()
的原因。
要避免这种情况,请在NullPointerException
或MenuItem
中初始化onPrepareOptionsMenu(..)
。
onCreateOptionsMenu(..)
更新但更重要的是您应该执行public boolean onPrepareOptionsMenu(Menu menu){
refreshMenuItem = menu.findItem(R.id.action_refresh);
return true;
}
的位置。只有在您使用的所有AsyncTask
类成员都处于安全状态时才能执行#34 ;;我的意思是,如果您的Activity
有Activity
成员,并且您从SomeObject someObj
内拨打someObj.setSometh()
,则依赖于您AsyncTask
的假设}。
因此,您可以选择何时首先运行someObj != null
。