何时执行asynctask

时间:2014-03-19 16:50:33

标签: android android-asynctask android-activity

我有这项活动。在内部活动我有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引用。有解决方法吗?

1 个答案:

答案 0 :(得分:1)

是的,有。当您在AsyncTask中运行onCreate(..)时,您的MenuItem尚未初始化 - 因为当用户按下相应的按钮时,由于某些奇怪的原因,它会被初始化,这发生在{{1}内}}。这就是你获得onOptionsItemSelected()的原因。

要避免这种情况,请在NullPointerExceptionMenuItem中初始化onPrepareOptionsMenu(..)

onCreateOptionsMenu(..)

更新但更重要的是您应该执行public boolean onPrepareOptionsMenu(Menu menu){ refreshMenuItem = menu.findItem(R.id.action_refresh); return true; } 的位置。只有在您使用的所有AsyncTask类成员都处于安全状态时才能执行#34 ;;我的意思是,如果您的ActivityActivity成员,并且您从SomeObject someObj内拨打someObj.setSometh(),则依赖于您AsyncTask的假设}。

因此,您可以选择何时首先运行someObj != null