如何在片段中的Asynctask之后发送notifyDataSetChanged

时间:2013-09-30 12:17:59

标签: java android fragment

如果应用程序崩溃,我无法调用notifyDataSetChanged。

ListFragment类:

public class ServerListFragment extends ListFragment implements OnTaskCompleteListener {


  private AsyncTaskManager mAsyncTaskManager;
private ServersDataSource datasource;
private ArrayList<Server> servers;
  private boolean paused = false;
  private boolean generateList = true;
    private String operation = "";
/**
 * The serialization (saved instance state) Bundle key representing the
 * activated item position. Only used on tablets.
 */
private static final String STATE_ACTIVATED_POSITION = "activated_position";

/**
 * The fragment's current callback object, which is notified of list item
 * clicks.
 */
private Callbacks mCallbacks = sDummyCallbacks;

/**
 * The current activated item position. Only used on tablets.
 */
private int mActivatedPosition = ListView.INVALID_POSITION;

/**
 * A callback interface that all activities containing this fragment must
 * implement. This mechanism allows activities to be notified of item
 * selections.
 */
public interface Callbacks {
    /**
     * Callback for when an item has been selected.
     */
    public void onItemSelected(String id);
}

/**
 * A dummy implementation of the {@link Callbacks} interface that does
 * nothing. Used only when this fragment is not attached to an activity.
 */
private static Callbacks sDummyCallbacks = new Callbacks() {
    @Override
    public void onItemSelected(String id) {
    }
};

/**
 * Mandatory empty constructor for the fragment manager to instantiate the
 * fragment (e.g. upon screen orientation changes).
 */
public ServerListFragment() {
}
/*
 * Default list adapter
 */
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // retainInstance and survive on configuration changes (rotation)
    setRetainInstance(true);


    // Create manager and set this activity as context and listener
    mAsyncTaskManager = new AsyncTaskManager(getActivity(), this);
    // Handle task that can be retained before
    mAsyncTaskManager.handleRetainedTask(getActivity().getLastNonConfigurationInstance());

    // start async task
    getServersServices();


}


@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // Restore the previously serialized activated item position.
    if (savedInstanceState != null
            && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
        setActivatedPosition(savedInstanceState
                .getInt(STATE_ACTIVATED_POSITION));
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // Activities containing this fragment must implement its callbacks.
    if (!(activity instanceof Callbacks)) {
        throw new IllegalStateException(
                "Activity must implement fragment's callbacks.");
    }

    mCallbacks = (Callbacks) activity;
}

@Override
public void onDetach() {
    super.onDetach();

    // Reset the active callbacks interface to the dummy implementation.
    mCallbacks = sDummyCallbacks;
}

@Override
public void onListItemClick(ListView listView, View view, int position,
        long id) {
    super.onListItemClick(listView, view, position, id);

    // Notify the active callbacks interface (the activity, if the
    // fragment is attached to one) that an item has been selected.
    mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (mActivatedPosition != ListView.INVALID_POSITION) {
        // Serialize and persist the activated item position.
        outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
    }
}

/**
 * Turns on activate-on-click mode. When this mode is on, list items will be
 * given the 'activated' state when touched.
 */
public void setActivateOnItemClick(boolean activateOnItemClick) {
    // When setting CHOICE_MODE_SINGLE, ListView will automatically
    // give items the 'activated' state when touched.
    getListView().setChoiceMode(
            activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
                    : ListView.CHOICE_MODE_NONE);
}

private void setActivatedPosition(int position) {
    if (position == ListView.INVALID_POSITION) {
        getListView().setItemChecked(mActivatedPosition, false);
    } else {
        getListView().setItemChecked(position, true);
    }

    mActivatedPosition = position;
}

public void notifyDataSetChanged() {
    ((BaseAdapter) getListAdapter()).notifyDataSetChanged();
}


public void getServersServices() {
    datasource = new ServersDataSource(getActivity());
    datasource.open();
    datasource.emptyServersTable();
    operation = "GetSevers";
    mAsyncTaskManager.setupTask(new Task(getResources(), getActivity(), getResources().getString(R.string.refreshing), operation, 0, ""));
}


public void onTaskComplete(Task task) {
    if (task.isCancelled()) {
        // Report about cancel
        if (DEBUG) Log.i(TAG, "ServersStatus onTaskComplete task cancel");
    } else {
            // Get result
            Boolean result = null;
            try {
                result = task.get();
            } catch (Exception e) {
                 if (DEBUG) Log.e(TAG, "ServersStatus onTaskComplete error: " + e.toString());
            }
            // Report about result
            servers = datasource.getAllServers();
            if(servers.size() > 0 && generateList){
                DummyContent.setContext(servers);
                notifyDataSetChanged();
            }

        operation = "";
    }
    generateList = true;
}

// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
       // Get extra data included in the Intent
       String message = intent.getStringExtra("message");
       if (message.equals("Refresh list")) {
           servers = datasource.getAllServers();
           getServersServices();
       }
    }
};
}

错误日志:

> 09-30 15:15:39.360: E/AndroidRuntime(14322): FATAL EXCEPTION: main
> 09-30 15:15:39.360: E/AndroidRuntime(14322):
> java.lang.NullPointerException 09-30 15:15:39.360:
> E/AndroidRuntime(14322):  at
> com.ww.www.ServerListFragment.notifyDataSetChanged(ServerListFragment.java:307)
> 09-30 15:15:39.360: E/AndroidRuntime(14322):  at
> com.ww.www.ServerListFragment.onTaskComplete(ServerListFragment.java:385)
> 09-30 15:15:39.360: E/AndroidRuntime(14322):  at
> com.ww.www.core.AsyncTaskManager.onComplete(AsyncTaskManager.java:67)
> 09-30 15:15:39.360: E/AndroidRuntime(14322):  at
> com.ww.www.core.Task.onPostExecute(Task.java:330) 09-30 15:15:39.360:
> E/AndroidRuntime(14322):  at
> com.ww.www.core.Task.onPostExecute(Task.java:1) 09-30 15:15:39.360:
> E/AndroidRuntime(14322):  at
> android.os.AsyncTask.finish(AsyncTask.java:631) 09-30 15:15:39.360:
> E/AndroidRuntime(14322):  at
> android.os.AsyncTask.access$600(AsyncTask.java:177) 09-30
> 15:15:39.360: E/AndroidRuntime(14322):    at
> android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
> 09-30 15:15:39.360: E/AndroidRuntime(14322):  at
> android.os.Handler.dispatchMessage(Handler.java:99) 09-30
> 15:15:39.360: E/AndroidRuntime(14322):    at
> android.os.Looper.loop(Looper.java:137) 09-30 15:15:39.360:
> E/AndroidRuntime(14322):  at
> android.app.ActivityThread.main(ActivityThread.java:4898) 09-30
> 15:15:39.360: E/AndroidRuntime(14322):    at
> java.lang.reflect.Method.invokeNative(Native Method) 09-30
> 15:15:39.360: E/AndroidRuntime(14322):    at
> java.lang.reflect.Method.invoke(Method.java:511) 09-30 15:15:39.360:
> E/AndroidRuntime(14322):  at
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
> 09-30 15:15:39.360: E/AndroidRuntime(14322):  at
> com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775) 09-30
> 15:15:39.360: E/AndroidRuntime(14322):    at
> dalvik.system.NativeStart.main(Native Method)

4 个答案:

答案 0 :(得分:1)

我可以看到你正在使用eclipse提供的关于DummyContent类的主细节流的示例,但是你已经删除了这段代码的安静,这对于这段代码来说至关重要

setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(getActivity(),
                android.R.layout.simple_list_item_activated_1,
                android.R.id.text1, 
                DummyContent.ITEMS));

将它放回onCreate

答案 1 :(得分:0)

无法在代码中看到适配器。请设置适配器。

答案 2 :(得分:0)

我不会在任何地方看到ListFragment.setListAdapter。这里发现崩溃的原因是什么。

public void notifyDataSetChanged() {
    ((BaseAdapter) getListAdapter()).notifyDataSetChanged();
}

在这里,您尝试获取List适配器并调用notifyDataSetChanged()。由于没有列表适配器,它将导致NPE。

答案 3 :(得分:0)

问题可能在于这种方法:

public void notifyDataSetChanged() {
    ((BaseAdapter) getListAdapter()).notifyDataSetChanged();
}

我猜getListAdapter()返回null因为我无法看到你在任何地方设置任何适配器到这个ListFragment。