2012-08-17 50 views
1

我已經遇到了一個與我的Android開發有關的真氣問題 - 每當我呼叫startActivityForResult(this, Notepadv3.class);,我的應用程序skipps直接在它上面,而不是啓動新的活動,也不會返回任何結果。就好像代碼不在那裏!Android正在跳過startActivityForResult,拋出異常

當我改變thismContextNullPointerException(I定義mContext如在類的開頭Context mContext;),應用程序崩潰。

我在不同的類中使用完全相同的代碼佈局,並且運行完美無缺。 我已驗證我正確地宣佈了清單中的活動。

我已經花了幾個小時搜索stackoverflow的答案,以及查找無數如何做這個特定的活動的例子,無濟於事。我正在學習如何編寫Android應用程序,因此使用Google的記事本教程來開發我的應用程序。感謝您提前給予的大力幫助!

代碼和堆棧跟蹤如下:

NoteEdit.java:(我已經脫脂的可讀性的緣故一些無關緊要的代碼),而不是推出新的意圖,從一個啓動的活動,從另一個活動

public class NoteEdit extends Activity implements OnClickListener { 


Context mContext; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mDbHelper = new NotesDbAdapter(this); 
    mDbHelper.open(); 

    setContentView(R.layout.note_edit); 
    setTitle(R.string.edit_item); 

    } 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent intent) { 
    if (requestCode == REQUEST_BARCODE) { 
     if (resultCode == RESULT_OK) { 
      barcode = (intent.getStringExtra("SCAN_RESULT")); 
      new updateBarcodeField().execute(""); 
     } else if (resultCode == RESULT_CANCELED) { 
     } 
    }else if (requestCode == REQUEST_NEW) { 
     System.out.println("REQUEST_NEW onActivityResult()."); 
    } 
} 


@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    saveState(); 
    outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId); 
} 


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

private void saveState(){ 
    System.out.println("saveState()"); 
    doorCall(); 
    mDbHelper.open(); 
    String title = mTitleText.getText().toString(); 
    String barcode = mBarcodeText.getText().toString(); 
    String price = mPriceText.getText().toString(); 
    Intent requestNew = new Intent(mContext, Notepadv3.class); 

    if (returnCode == 1){ 
     System.out.println("returnCode is 1. Calling validateFields()..."); 
     String errors = validateFields(title); 
     if (errors.length() > 0) { 
      Toast.makeText(this, "Oops! Need a title!", duration).show(); 
      System.out.println("Calling Notepadv3..."); 
      startActivityForResult(requestNew, REQUEST_NEW); 
     } 
    } 

    if (returnCode == 2){ 
     System.out.println("returnCode == 2 - Cancelling activity"); 

    }else{ 
     if (title.matches("")){ 
      System.out.println("Variable is null. Returning..."); 
      doorCall(); 
      mDbHelper.close(); 
      return; 
     }else{ 
      System.out.println("Checking mRowId for null"); 
      if (mRowId == null) { 

       Toast.makeText(this, "Success, product saved successfully", duration).show(); 
       System.out.println("Switching activity to 'NotesDbAdapter'"); 
       long id = mDbHelper.createNote(title, barcode, price); 
       mRowId = id; 
      }else{ 
       System.out.println("mRowId is not null. Calling updateNote"); 
       mDbHelper.updateNote(mRowId, title, barcode, price); 
      } 
     } 
    } 
    System.out.println("saveState() Finished"); 
    if (doorCall()==true){ 
     System.out.println("Database is Open"); 
    }else{ 
     System.out.println("Database is Closed"); 
    } 
} 

} 

Notepadv3.java:

public class Notepadv3 extends ListActivity implements OnClickListener { 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.notes_list); 
    mDbHelper = new NotesDbAdapter(this); 
    mDbHelper.open(); 

    mAddButton = (Button) findViewById(R.id.addButton); 
    mAddButton.setOnClickListener(this); 
    mScanButton = (Button) findViewById(R.id.scanButtonList); 
    mScanButton.setOnClickListener(this); 

    fillData(); 
    registerForContextMenu(getListView()); 
} 

@SuppressWarnings("deprecation") 
private void fillData() { 
    Cursor notesCursor = mDbHelper.fetchAllNotes(); 
    startManagingCursor(notesCursor); 

    // Create an array to specify the fields we want to display in the list (only TITLE) 
    String[] from = new String[]{NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_PRICE}; 

    // and an array of the fields we want to bind those fields to (in this case just text1) 
    int[] to = new int[]{R.id.text1, R.id.text2}; 

    // Now create a simple cursor adapter and set it to display 
    SimpleCursorAdapter notes = 
      new SimpleCursorAdapter(this, R.layout.notes_row, notesCursor, from, to); 
    setListAdapter(notes);   
} 

public void onClick(View v) { 
    switch (v.getId()) { 
    case R.id.addButton: 
     createNote(); 
     break; 

    case R.id.scanButtonList: 
     Intent intent = new Intent("com.google.zxing.client.android.SCAN"); 
     intent.putExtra("SCAN_MODE", "ONE_D_MODE"); 
     startActivityForResult(intent, REQUEST_BARCODE);   

    } 
} 
@Override 
public void onCreateContextMenu(ContextMenu menu, View v, 
     ContextMenuInfo menuInfo) { 
    super.onCreateContextMenu(menu, v, menuInfo); 
    menu.add(0, DELETE_ID, 0, R.string.menu_delete); 
} 

@Override 
public boolean onContextItemSelected(MenuItem item) { 
    switch(item.getItemId()) { 
    case DELETE_ID: 
     AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 
     mDbHelper.deleteNote(info.id); 
     fillData(); 
     return true; 
    } 
    return super.onContextItemSelected(item); 
} 

public void createNote() { 
    Intent i = new Intent(this, NoteEdit.class); 
    startActivityForResult(i, ACTIVITY_CREATE); 
} 

private void viewNote() { 
    System.out.println("viewNote(). Starting NoteEdit..."); 
    Intent i = new Intent(this, NoteView.class); 
    i.putExtra(NotesDbAdapter.KEY_BARCODE, barcode); 
    startActivityForResult(i, ACTIVITY_EDIT); 
} 

@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    super.onListItemClick(l, v, position, id); 
    Intent i = new Intent(this, NoteEdit.class); 
    i.putExtra(NotesDbAdapter.KEY_ROWID, id); 
    startActivityForResult(i, ACTIVITY_EDIT); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent intent) { 
    super.onActivityResult(requestCode, resultCode, intent); 
    System.out.println("Notepadv3. requestCode is " + requestCode + ", and resultCode is " + resultCode); 
    if (requestCode == REQUEST_BARCODE) { 
     if (resultCode == RESULT_OK) { 
      barcode = (intent.getStringExtra("SCAN_RESULT")); 
      System.out.println("Calling viewNote()..."); 
      viewNote(); 
     } else if (resultCode == RESULT_CANCELED) { 
     } else if (resultCode == RESULT_FIRST_USER) { 
     } 
    }else if (requestCode == REQUEST_NEW){ 
     System.out.println("Notepadv3. requestCode is REQUEST_NEW. Calling createNote()..."); 
     createNote(); 
    } 
    super.onActivityResult(requestCode, resultCode, intent); 
    fillData(); 
} 
} 

Stack trace:

FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to pause activity {com.android.demo.notepad3/com.android.demo.notepad3.NoteEdit}: java.lang.NullPointerException 
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2706) 
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2662) 
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2640) 
at android.app.ActivityThread.access$800(ActivityThread.java:123) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:137) 
at android.app.ActivityThread.main(ActivityThread.java:4424) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException 
at android.content.ComponentName.<init>(ComponentName.java:75) 
at android.content.Intent.<init>(Intent.java:3148) 
at com.android.demo.notepad3.NoteEdit.saveState(NoteEdit.java:206) 
at com.android.demo.notepad3.NoteEdit.onPause(NoteEdit.java:187) 
at android.app.Activity.performPause(Activity.java:4590) 
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1195) 
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2693) 
+0

爲什麼你需要mContext?你已經在活動中,所以爲什麼不使用Activity_name.this本身 – pixelscreen 2012-08-17 10:59:26

+0

什麼是doorCall();有可能在saveState()內有一些變量爲空。將變量打印到logcat並查看返回的內容null – pixelscreen 2012-08-17 11:01:30

+2

另外,在'onPause()中開始一個新的活動對我來說看起來很可疑。 (saveState()在onPause()中調用) – 2012-08-17 11:03:52

回答

1

First of all, if you use mContext, you should initialize it in the onCreate method:

mContext=getApplicationContext(); 
//I recommend using the application context for avoiding memory leaks 

Don't start an Activity from the onPause method.

+0

好的。那麼我應該從一種新方法開始嗎?並調用這個方法來代替現有的代碼? – TrippySquidsman 2012-08-17 11:12:23

+0

是的,只要你不從onPause方法調用這個方法。這與直接啓動活動具有相同的效果:P – 2012-08-17 11:14:59

+0

等待一秒...您在哪裏定義了returnCode變量? – 2012-08-17 11:16:53

0

I fixed it!!!

This won't be a fix for most that are looking for answers, but I hope I can point you in the right direction. As new as I am to Android (and Java in general), I am still totally convinced that this 'skipping' of code is, in fact, a bug.

However! As I'm calling saveState(),單獨的課程,然後從第一個意圖源自的課程啓動活動,我簡單地將其替換爲return;。是的,在學習邏輯的時候還是很狡猾的,但是它確實存在。簡單,優雅的解決方案(與之前存在的可怕代碼相比,簡單而優雅:P)