简体   繁体   中英

NullPointerException in onRestoreInstanceState

SwiperActivity below, extends SherlockFragmentActivity from the ActionBarSherlock 4.0.2 library. I can only get this after loading loads of different apps, then switching back, on an Asus Eee Pad Transformer TF101 on ICS 4.0.3 OTA, as well as the Galaxy Nexus on ICS 4.0.4 OTA. I'm not sure if this is obviously an ICS 4.0.3 bug (it appears to match up with ICS source code here http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/com/android/internal/policy/impl/PhoneWindow.java#PhoneWindow.getPanelState%28int%2Cboolean%29 ).

I also get this on ActionBarSherlock 4.0.0 and 4.0.1.

I am not overriding onRestoreInstanceState or any of the instances or states.

(I also log the first line of each overridden Activity method eg " SwiperAct.onCreate 0 " and at the end, " SwiperAct.onCreate 99 ", to try to pinpoint which method causes this.)

04-16 14:30:57.710: D/dalvikvm(667): GC_CONCURRENT freed 2692K, 71% free 8750K/30023K, paused 2ms+4ms
04-16 14:30:58.140: D/dalvikvm(667): GC_CONCURRENT freed 120K, 69% free 9362K/30023K, paused 3ms+4ms
04-16 14:30:58.480: D/dalvikvm(667): GC_CONCURRENT freed 16K, 67% free 10207K/30023K, paused 4ms+5ms
04-16 14:31:00.700: D/dalvikvm(18313): Late-enabling CheckJNI
04-16 14:31:00.700: I/ActivityManager(557): Start proc com.company.appname for activity com.company.appname/.SwiperActivity: pid=18313 uid=10011 gids={3003, 1015}
04-16 14:31:00.720: D/WindowManager(557): readLidState, sw:1
04-16 14:31:00.720: D/WindowManager(557): adjustConfigurationLw, config:{1.0 0mcc0mnc (no locale) layoutdir=0 sw800dp w1280dp h752dp xlrg land ?uimode ?night finger qwerty/v/v -nav/v} mLidOpen:1 mHasDockFeature:true mHasHallSensorFeature:true config.hardKeyboardHidden:1
04-16 14:31:00.730: D/OpenGLRenderer(18274): Flushing caches (mode 1)
04-16 14:31:00.730: D/dalvikvm(18313): Debugger has detached; object registry had 1 entries
04-16 14:31:00.900: D/OpenGLRenderer(18274): Flushing caches (mode 0)
04-16 14:31:00.950: D/OpenGLRenderer(667): Flushing caches (mode 0)
04-16 14:31:00.970: E/SwiperAct.onCreate 0(18313): starting...
04-16 14:31:00.980: D/SwiperAct.onSingleUse 0(18313): starting...
04-16 14:31:01.050: D/SQLiteUtil(18313): create DatabaseOpenHelper instance
04-16 14:31:01.050: D/SQLiteUtil(18313): create DatabaseOpenHelper instance
04-16 14:31:01.080: V/SQLiteOpenHelper(18313): onOpen()
04-16 14:31:01.100: V/SQLiteOpenHelper(18313): onOpen()
04-16 14:31:01.100: D/SwiperAct.onSingleUse 99(18313): ending...
04-16 14:31:01.120: D/dalvikvm(18313): GC_CONCURRENT freed 209K, 5% free 6728K/7047K, paused 4ms+2ms
04-16 14:31:01.190: E/SwiperAct.onCreate 99(18313): ending...
04-16 14:31:01.200: D/AndroidRuntime(18313): Shutting down VM
04-16 14:31:01.200: W/dalvikvm(18313): threadid=1: thread exiting with uncaught exception (group=0x40a7b1f8)
04-16 14:31:01.200: E/AndroidRuntime(18313): FATAL EXCEPTION: main
04-16 14:31:01.200: E/AndroidRuntime(18313): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.appname/com.company.appname.SwiperActivity}: java.lang.NullPointerException
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.ActivityThread.access$600(ActivityThread.java:123)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.os.Looper.loop(Looper.java:137)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.ActivityThread.main(ActivityThread.java:4424)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at java.lang.reflect.Method.invokeNative(Native Method)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at java.lang.reflect.Method.invoke(Method.java:511)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at dalvik.system.NativeStart.main(Native Method)
04-16 14:31:01.200: E/AndroidRuntime(18313): Caused by: java.lang.NullPointerException
04-16 14:31:01.200: E/AndroidRuntime(18313):    at com.android.internal.policy.impl.PhoneWindow$PanelFeatureState.onRestoreInstanceState(PhoneWindow.java:3341)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at com.android.internal.policy.impl.PhoneWindow.restorePanelState(PhoneWindow.java:1663)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1619)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.Activity.onRestoreInstanceState(Activity.java:906)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.Activity.performRestoreInstanceState(Activity.java:878)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1100)
04-16 14:31:01.200: E/AndroidRuntime(18313):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
04-16 14:31:01.200: E/AndroidRuntime(18313):    ... 11 more
04-16 14:31:01.200: W/ActivityManager(557):   Force finishing activity com.company.appname/.SwiperActivity
04-16 14:31:01.500: D/dalvikvm(18313): GC_CONCURRENT freed 177K, 4% free 7027K/7303K, paused 1ms+3ms
04-16 14:31:01.610: D/dalvikvm(18313): GC_CONCURRENT freed 114K, 3% free 7455K/7623K, paused 6ms+3ms
04-16 14:31:01.740: D/dalvikvm(18313): GC_CONCURRENT freed 117K, 3% free 7900K/8071K, paused 3ms+3ms
04-16 14:31:01.750: D/WindowManager(557): readLidState, sw:1
04-16 14:31:01.750: D/WindowManager(557): adjustConfigurationLw, config:{1.0 0mcc0mnc (no locale) layoutdir=0 sw800dp w1280dp h752dp xlrg land ?uimode ?night finger qwerty/v/v -nav/v} mLidOpen:1 mHasDockFeature:true mHasHallSensorFeature:true config.hardKeyboardHidden:1
04-16 14:31:01.750: W/ActivityManager(557): Activity pause timeout for ActivityRecord{41568e50 com.company.appname/.SwiperActivity}

I cannot divulge the source code as it is for work - however I've done some renaming and stripped it down. However, after stripping it down to just the parts which I suspect cause the bug, and enabling the line that causes the bug, the bug doesn't happen anymore!

So this source code is just to give a clue to anyone else who experiences this, as to where to look. This code doesn't actually trigger the bug.

onCreate calls showSingleUse, which spawns a SingleUseFragment, which calls onSingleUse in the activity (because it implements an interface called OnFragmentUtilityListener). onSingleUse then calls an AsyncTask which does a findViewById in its onPreExecute.

Disabling the findViewById, and moving it to onCreate, solves the problem.

SwiperActivity.java:

import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity;

public class SwiperActivity extends SherlockFragmentActivity implements OnFragmentUtilityListener {
TextView textviewLastUpdated; // this is how the NPE was fixed
ReloadTask reloadTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    textviewLastUpdated = (TextView) findViewById(R.id.textviewLastUpdated); // this is how the NPE was fixed
    showSingleUse(this);
}
public static void showSingleUse(FragmentActivity activity) {
    try {
        if (activity.getSupportFragmentManager().findFragmentByTag("singleusefragment") == null) {
            activity.getSupportFragmentManager().beginTransaction().add(new SingleUseFragment(), "singleusefragment").commit();
        }
    } catch (IllegalStateException e) {}
}
@Override
public void onSingleUse() {
    startReloadTask();
}
private class ReloadTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
        showLoading();
    }
    @Override
    protected Void doInBackground(Void... arg0) {
        return null;
    }
    @Override
    protected void onPostExecute(Void result) {
        hideLoading();
    }
}
public static boolean allowsExecutorChange() {
    return Build.VERSION.SDK_INT > 10;
}
void startReloadTask() {
    reloadTask = new ReloadTask();
    if (allowsExecutorChange()) {
        reloadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    } else {
        reloadTask.execute();
    }
}
void showLoading() {
    // this was causing the NPE!
    //TextView textviewLastUpdated = (TextView) findViewById(R.id.textviewLastUpdated);
    if (textviewLastUpdated!=null) textviewLastUpdated.setText("Loading...");
}
void hideLoading() {
    // this was causing the NPE!
    //TextView textviewLastUpdated = (TextView) findViewById(R.id.textviewLastUpdated);
    if (textviewLastUpdated!=null) textviewLastUpdated.setText("Loaded!");
}
@Override
public void onDismissedDialog(String tag, Object data) {}
@Override
public void onClickedPositiveDialog(String tag, Object data) {}

}

OnFragmentUtilityListener.java:

public interface OnFragmentUtilityListener {
public void onDismissedDialog(String tag, Object data);
public void onClickedPositiveDialog(String tag, Object data);
public void onSingleUse();
}

SingleUseFragment.java:

/** hack-ish way to detect rotation and not do it again */
public class SingleUseFragment extends Fragment {
boolean wasRotating = false;
@Override
public void onActivityCreated(Bundle state) {
    super.onActivityCreated(state);
    setRetainInstance(true);
}
static SingleUseFragment newInstance() {
        return new SingleUseFragment();
    }
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (!wasRotating) ((OnFragmentUtilityListener) activity).onSingleUse();
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    wasRotating = true;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM