2012-08-17 48 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)