2012-08-31 115 views
2

我爲我的過濾器搜索欄創建了一個onDestroy方法,並遇到了一個小問題。空指針異常錯誤ANDROID

這裏是我的logcat:

09-01 01:55:40.147: E/AndroidRuntime(1014): FATAL EXCEPTION: main 
09-01 01:55:40.147: E/AndroidRuntime(1014): java.lang.RuntimeException: Unable to destroy activity {com.stts.sparetimetradingsystem/com.stts.sparetimetradingsystem.employer.HomepageEmployerActivity}: java.lang.NullPointerException 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3655) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3673) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.app.ActivityThread.access$2900(ActivityThread.java:125) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.os.Handler.dispatchMessage(Handler.java:99) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.os.Looper.loop(Looper.java:123) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at java.lang.reflect.Method.invoke(Method.java:521) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at dalvik.system.NativeStart.main(Native Method) 
09-01 01:55:40.147: E/AndroidRuntime(1014): Caused by: java.lang.NullPointerException 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at com.stts.sparetimetradingsystem.employer.HomepageEmployerActivity.onDestroy(HomepageEmployerActivity.java:340) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3642) 
09-01 01:55:40.147: E/AndroidRuntime(1014):  ... 11 more 

這是我的代碼:

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    searchBarEmployer.removeTextChangedListener(filterTextWatcher); <--- LINE 340 
} 

* *編輯 THIS IS MY登錄代碼的用戶輸入正確後,將切換到主頁證書。

public class LoginEmployerActivity extends Activity { 
Button btnLoginEmployer; 
Button btnLinkToEmployerRegisterScreen; 
EditText inputEmail; 
EditText inputPassword; 
TextView loginErrorMsg; 
TextView forgotPassword; 

// JSON Response node names 
private static String KEY_SUCCESS = "success"; 
private static String KEY_ERROR = "error"; 
private static String KEY_ERROR_MSG = "error_msg"; 
private static String KEY_UID = "uid"; 
private static String KEY_NAME = "name"; 
private static String KEY_CNAME = "cname"; 
private static String KEY_EMAIL = "email"; 
private static String KEY_CREATED_AT = "created_at"; 
private ProgressDialog pDialog; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.login_employer); 

    // Importing all assets like buttons, text fields 
    inputEmail = (EditText) findViewById(R.id.loginEmployerEmail); 
    inputPassword = (EditText) findViewById(R.id.loginEmployerPassword); 
    btnLoginEmployer = (Button) findViewById(R.id.btnLoginEmployer); 
    btnLinkToEmployerRegisterScreen = (Button) findViewById(R.id.btnLinkToEmployerRegisterScreen); 
    loginErrorMsg = (TextView) findViewById(R.id.login_error); 
    forgotPassword = (TextView) findViewById(R.id.link_to_forgetPassword); 

    // Login button Click Event 
    btnLoginEmployer.setOnClickListener(new View.OnClickListener() { 

     public void onClick(View view) { 
      // Checking for server respond 
       new LoginEmployer().execute(); 
      } 
     } 
    }); 

    // Link to Register Screen 
    btnLinkToEmployerRegisterScreen 
      .setOnClickListener(new View.OnClickListener() { 

       public void onClick(View view) { 
        Intent i = new Intent(getApplicationContext(), 
          RegisterEmployerActivity.class); 
        startActivity(i); 
        finish(); 
       } 
      }); 

    // Link to forgot password link 
    forgotPassword.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      // Switching to forgot password screen 
      Intent i = new Intent(getApplicationContext(), 
        ForgotPasswordEmployerActivity.class); 
      startActivity(i); 
     } 
    }); 
} 

// Background ASYNC Task to login by making HTTP Request 
class LoginEmployer extends AsyncTask<String, String, String> { 

    // Before starting background thread Show Progress Dialog 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(LoginEmployerActivity.this); 
     pDialog.setMessage("Authenticating..."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(false); 
     pDialog.show(); 
    } 

    // Checking login in background 
    protected String doInBackground(String... params) { 
     runOnUiThread(new Runnable() { 
      public void run() { 

       String email = inputEmail.getText().toString(); 
       String password = inputPassword.getText().toString(); 
       EmployerFunctions employerFunctions = new EmployerFunctions(); 
       JSONObject json = employerFunctions.loginUser(email, 
         password); 

       // check for login response 
       try { 
        if (json.getString(KEY_SUCCESS) != null) { 
         loginErrorMsg.setText(""); 
         String res = json.getString(KEY_SUCCESS); 
         if (Integer.parseInt(res) == 1) { 
          // user successfully logged in 
          // Store user details in SQLite Database 
          DatabaseHandlerEmployer dbe = new DatabaseHandlerEmployer(
            getApplicationContext()); 
          JSONObject json_user = json 
            .getJSONObject("user"); 

          // Clear all previous data in database 
          employerFunctions 
            .logoutUser(getApplicationContext()); 
          dbe.addUser(
            json_user.getString(KEY_NAME), 
            //json_user.getString(KEY_CNAME), 
            json_user.getString(KEY_EMAIL), 
            json.getString(KEY_UID), 
            json_user.getString(KEY_CREATED_AT)); 
          // Launch Employer homePage Screen 
          Intent homepage = new Intent(
            getApplicationContext(), 
            HomepageEmployerActivity.class); 

          // Close all views before launching Employer 
          // homePage 
          homepage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
          startActivity(homepage); 

          // Close Login Screen 
          finish(); 
         } else { 
          // Error in login 
          loginErrorMsg 
            .setText("Invalid username/password"); 
         } 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     return null; 
    } 

    // After completing background task Dismiss the progress dialog 
    protected void onPostExecute(String file_url) { 
     // dismiss the dialog once done 
     pDialog.dismiss(); 
    } 
} 

}

+0

我希望你的'searchBarEmployer'已經被正確初始化和引用。 – Swayam

+0

我如何初始化? searchBarEmployer是我的editText –

+0

請在下面檢查我的答案。我在那裏給了代碼。 :) – Swayam

回答

2

確保您searchBarEmployer已初始化和正確引用。

EditText searchBarEmployer ; // outside onCreate, global to class 

裏面的onCreate(),

searchBarEmployer = (EditText)findViewById(R.id.editTextIdInXML); 

此外,

@Override 
protected void onDestroy() { 
    searchBarEmployer.removeTextChangedListener(filterTextWatcher); 
    super.onDestroy(); 

} 
+0

是。現在嘗試這個改變。 –

+0

是的,我做了所有這些。現在沒有錯誤,但在我無法進入主頁之後。登錄後應該進入主頁,但它回到登錄頁面。 –

+0

並確保您在findById()中使用EditText的正確ID。它是您的XML文件中您已經定義了EditText的佈局的id。還要確保super.onDestroy()是你函數中的最後一個語句。 – Swayam

1

你沒有錯。如果你重寫onCreate()(或者一般的構造函數類似的方法),那麼拇指的規則是調用super.onCreate()FIRST(要初始化所有stull超類可能需要的等)然後做你的東西。但是如果你重寫onDestroy()(或者一般的析構函數類似的方法),那麼拇指規則就是你在onCreate()中以相反順序處理所有的清理事件。先清除自己的東西,然後撥打super.onDestroy()作爲LAST之一。否則(就像你做的那樣)可能會導致很多問題,因爲超類可以簡單地清理很多東西(如內部變量,引用等),而且你的代碼已經崩潰了。 Reaarange你onDestroy()這樣的:

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

There'is還選擇你的searchBarEmployer簡直是零,所以這可能可能是更安全:

@Override 
protected void onDestroy() { 
    if(searchBarEmployer != null) { 
     searchBarEmployer.removeTextChangedListener(filterTextWatcher); 
    } 
    super.onDestroy(); 
} 
+0

謝謝我現在試試。 –

0

請將調試點,並確保searchBarEmployer是不爲空。

由於前面執行的某些步驟而在null的情況下,在此語句前放置空檢查。你

if(searchBarEmployer != null) { 
// Place operation here... 
} 

而且應該移動

super.onDestroy(); 

作爲方法的最後一條語句。

編輯我的意思是......

@Override 
protected void onDestroy() { 
    if(searchBarEmployer != null) { // <---- PLACE NULL CHECK 
     searchBarEmployer.removeTextChangedListener(filterTextWatcher); 
    } 
    super.onDestroy(); // <--- LAST STATEMENT 
} 
+0

把你的意思轉到最後一句話是什麼意思? –

0

如有需要請初始化searchBarEmployer。 如果searchBarEmployer是一個文本視圖,則將其聲明爲top,然後執行searchBarEmployer =(TextView)findViewById(R.id ....);等等,然後使用它。

避免使用 TextView searchBarEmployer = null; 種方法。