开发者

NullPointerException when I call a custom activity subclass

开发者 https://www.devze.com 2023-02-28 03:13 出处:网络
I have a generic base activity with some authentication code in the onStart() method that I need to be executed in every Activity. However, if I subclass this in one of my real activities, and try to

I have a generic base activity with some authentication code in the onStart() method that I need to be executed in every Activity. However, if I subclass this in one of my real activities, and try to launch one of them, I get a NPE.

Here's some code I'm using

Login screen

public class Login extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        configureEventHandlers();
    }

    private void configureEventHandlers()
    {
        mLoginBtn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                mLoginModel.setPassword(mPwdTxt.getText().toString());
                mLoginModel.setUserName(mLoginTxt.getText().toString());

                // Call the network

                List<NameValuePair> paramTable = new ArrayList<NameValuePair>(2);
                paramTable.add(new BasicNameValuePair("email", mLoginModel.getUserName()));
                paramTable.add(new BasicNameValuePair("password", mLoginModel.getPassword()));
                mSpinner = ProgressDialog.show(Login.this, "Working", "Logging in ..");
                login(paramTable);              
            }
        });
        mClearBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mLoginTxt.setText("");
                mPwdTxt.setText("");
            }
        });

    }
    private void login(List<NameValuePair> paramTable) {
        NetworkParams params = new NetworkParams();
        params.setMethodName("ValidateLogin");
        params.setUrl(UserContext.GLOBAL_IP);
        params.setParams(paramTable);
        ResponseHandler handler = new ResponseHandler() {
            @Override
            public void requestSucceded(NetworkResult result) {
                parseResponseFromNetwork(result.getResponseMessage());
            }

            @Override
            public void requestFailed(NetworkResult result) {
                new AlertDialog.Builder(Login.this).setTitle("Attention").setMessage("Could not contact PPK's servers. " +
                        "This could be because of low signal strength. Please try later or contact support if " +
                        "the problem persists")
                .setNeutralButton("Close", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dlg, int sumthin) { // do nothing Ð it will close on its own
                    } 
                }
                ).show();
                mSpinner.dismiss();
            }
        };
        params.setHandler(handler);
        NetworkAccessClass nac = new NetworkAccessClass();
        nac.execute(params);
    }

    private void parseResponseFromNetwork(String responseMessage) {

        try {
            LoginXmlParser parser = new LoginXmlParser(mLoginModel);

            AsyncXmlParserParams params = new AsyncXmlParserParams();
            params.setHandler(parser);
            params.setListener(new AsyncXmlListener() {
                @Override
                public void asyncXmlParsingCompleted(Object parsedObject) {
                    // Dismiss the "waiting" progress indicator _after_ the parsing 
                    // the login xml. Avoids the delay between the pop up going away and Facility screen coming up.
                    mSpinner.dismiss();
                    mLoginModel = (LoginDataModel) parsedObject;
                    if(parsedObject == null || mLoginModel.getValid() == null) { 
                        authFailed(); 
                        return; 
                    }
                    if(((LoginDataModel) parsedObject).getValid()) {
                        // Works fine till here. The LoginDataModel object that I have looks okay
                        authSucceeded();
                    }
                    else
                    {
                        authFailed();
                    }
                }
            });
            params.setRequestString(responseMessage);

            AsyncXmlParser asyncParser = new AsyncXmlParser();
            asyncParser.execute(params);
        }
        catch(Exception e) {
            authFailed();
            Log.i("PPKMobileChargeCaptureException",e.getMessage());
        }
        return;
    }
    private void authSucceeded() {
        // Handle pushing facility screen
        try {
            Intent facilityLaunchIntent = new Intent(Login.this, FacilityScreen.class);
            Login.this.startActivity(facilityLaunchIntent);
        }
        catch(Exception ex)
        {
            String stackTrace = ex.getStackTrace().toString();
        }
    }
}

Facility Screen

public class FacilityScreen extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.facilityscreen);
        configureListView();
        configureEventHandlers();
        configureContext();
    }
    @Override
    protected void onStart()
    {
        super.onStart();
        if(mFacilityModel == null || mFacilityModel.size() == 0 || mUserPrefModel == null || mUserPrefModel.isEmpty()) {
            displayProgressIndicator();
            getPreferences();
            getFacilityList();
        }
    }
    @Override
    protected void onDestroy()
    {
        UserContext.clearUserPrefs();
        super.onDestroy();
    }
}

Facility Screen - Modified

public class FacilityScreen extends PPKBaseActivity
{
    // onCreate, onResume etc. **This doesn't work, NPE**
}

PPKBaseActivity

public class PPKBaseActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onStart()
    {
        if(!UserContext.isUserLoggedIn()) {
            this.finish();
        }
        super.onStart();
    }

    @Override
    protected void onResume()
    {
        super.onResume();
    }

    @Override
    protected void onPause()
    {
        super.onPause();
    }

    @Override
    protected void onStop()
    {
        super.onStop();
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
    }

    @Override
    protected void onRestart()
    {
        super.onRestart();
    }

}

Am I missing something really simple?

Thanks,

Teja.

EDIT: Added more code. Also want to 开发者_运维技巧mention that the breakpoint that I have in FacilityScreen's onCreate() method isn't hit at all.

EDIT2: Stack trace. (Not too familiar with Android + Eclipse, is this what is needed?)

ex  InvocationTargetException  (id=830084855920)    
    cause   RuntimeException  (id=830085267584) 
        cause   NullPointerException  (id=830085217952) 
        detailMessage   "Unable to instantiate activity ComponentInfo{com.PatientPoint.MCC/com.PatientPoint.MCC.FacilityScreen}: java.lang.NullPointerException" (id=830084938528)  
        stackState   (id=830084989144)  
        stackTrace  null    
    detailMessage   null    
    stackState   (id=830084855952)  
    stackTrace  null    
    target  RuntimeException  (id=830085267584) 


Thread [<3> main] (Suspended (exception RuntimeException))  
    ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2417  
    ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2512   
    ActivityThread.access$2200(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 119 
    ActivityThread$H.handleMessage(Message) line: 1863  
    ActivityThread$H(Handler).dispatchMessage(Message) line: 99 
    Looper.loop() line: 123 
    ActivityThread.main(String[]) line: 4363    
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 521  
    ZygoteInit$MethodAndArgsCaller.run() line: 860  
    ZygoteInit.main(String[]) line: 618 
    NativeStart.main(String[]) line: not available [native method]  

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.PatientPoint.MCC"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Login"
                  android:label="@string/app_name"
                  android:theme="@android:style/Theme.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".FacilityScreen"
                  android:label="" 
                  android:theme="@android:style/Theme.NoTitleBar">
            <intent-filter>
                <action android:name="CATEGORY_ALTERNATIVE"></action>
            </intent-filter>
         </activity>
    <uses-sdk android:minSdkVersion="4" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest> 

EDIT 3 (FINAL):

Thanks a lot for your help! My Apologies too, because I've figured out that the one line of code that I didn't include in the source was causing the exception. ex.printStackTrace() output with line numbers helped me narrow it down. I also had a SharedPreferenceManager in my PPKBaseActivity class that was responsible for all this. Apologies again, thanks for your time!


Thank you for the fast responses (and also for your patience).

You should remove the . (dot) from your

<activity android:name=".FacilityScreen"

line, so it would look like

<activity android:name="FacilityScreen"

Also, if you'd like to work with your other activities as well, you should list all of them inside the androidManifes.xml file.


04-21 19:25:11.646: ERROR/AndroidRuntime(339): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.PatientPoint.MCC/com.PatientPoint.MCC.FacilityScreen}: java.lang.NullPointerException
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.os.Looper.loop(Looper.java:123)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.ActivityThread.main(ActivityThread.java:4363)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at java.lang.reflect.Method.invokeNative(Native Method)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at java.lang.reflect.Method.invoke(Method.java:521)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at dalvik.system.NativeStart.main(Native Method)
04-21 19:25:11.646: ERROR/AndroidRuntime(339): Caused by: java.lang.NullPointerException
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:146)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at com.PatientPoint.MCC.PPKBaseActivity.<init>(PPKBaseActivity.java:20)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at com.PatientPoint.MCC.FacilityScreen.<init>(FacilityScreen.java:54)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at java.lang.Class.newInstanceImpl(Native Method)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at java.lang.Class.newInstance(Class.java:1479)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
04-21 19:25:11.646: ERROR/AndroidRuntime(339):     ... 11 more

There was a line of code in my PPKBaseActivity class that looks like this :

SharedPreferences currentUserPrefs = getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);

This was causing a NullPointerException for some reason. I'm not utilizing this right now, so I've removed that line of code and it seems to work.

0

精彩评论

暂无评论...
验证码 换一张
取 消