Android пропускает startActivityForResult, выбрасывая исключение
Я столкнулся с бешеной проблемой с моей разработкой Android - всякий раз, когда я звоню startActivityForResult(this, Notepadv3.class);
мое приложение прыгает прямо над ним, не запуская новое действие и не возвращая никакого результата. Это как если бы код не был там!
Когда я меняюсь this
в mContext
(Я определил mContext
как Context mContext;
в начале урока) приложение вылетает с NullPointerException
,
Я использовал точно такой же макет кода в другом классе, и он работает безупречно. Я подтвердил, что правильно объявляю действия в Манифесте.
Я потратил часы на поиск ответов в stackru, а также на поиски бесчисленных примеров того, как выполнять эту конкретную операцию, но безрезультатно. Я нахожусь в процессе изучения того, как писать приложения для Android, и, таким образом, использовал учебник Google Notepad для создания своего приложения. Спасибо за высоко оцененную помощь заранее!
Трассировка кода и стека выглядит следующим образом:
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(); } }
Трассировки стека:
ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: главная java.lang.RuntimeException: невозможно приостановить действие {com.android.demo.notepad3/com.android.demo.notepad3.NoteEdit}: java.lang.NullPointerException на android.app.ActivityThread.performPauseActivity(ActivityThread.java:2706) на android.app.ActivityThread.performPauseActivity(ActivityThread.java:2662) на android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2640) на android.app.ActivityThread.access$800(ActivityThread.java:123) на android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158) на android.os.Handler.dispatchMessage(Handler.java:99) на android.os.Looper.loop(Looper.java:137) на android.app.ActivityThread.main(ActivityThread.java:4424) в java.lang.reflect.Method.invokeNative(родной метод) в java.lang.reflect.Method.invoke(Method.java:511) на com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) в dalvik.system.NativeStart.main(собственный метод) Вызывается: java.lang.NullPointerException на android.content.ComponentName.(ComponentName.java:75) на android.content.Intent. (Intent.java:3148) на com.android.demo.notepad3.NoteEdit.saveState(NoteEdit.java:206) на com.android.demo.notepad3.NoteEdit.onPause(NoteEdit.java:187) на android.app.Activity.performPause(Activity.java:4590) на android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1195) на android.app.ActivityThread.performPauseActivity(ActivityThread.java:2693)
2 ответа
Прежде всего, если вы используете mContext, вы должны инициализировать его в методе onCreate:
mContext=getApplicationContext();
//I recommend using the application context for avoiding memory leaks
Не запускайте Activity из метода onPause.
Я починил это!!!
Это не будет исправлением для большинства, кто ищет ответы, но я надеюсь, что смогу указать вам правильное направление. Несмотря на то, что я новичок в Android (и Java в целом), я все еще полностью убежден, что этот "пропуск" кода, на самом деле, является ошибкой.
Тем не мение! Как я звоню saveState()
из другого действия, вместо запуска нового намерения, которое запускает действие из отдельного класса, который затем запускает действие из класса, из которого произошло первое намерение, я просто заменил его на return;
, Да - все еще довольно сумасшедший с изучением логики, но это так. Простое, элегантное решение (ну, простое и элегантное по сравнению с ужасным кодом, который существовал до него:P)