Android正在跳过startActivityForResult,抛出异常

时间:2012-08-17 10:57:52

标签: android android-intent android-context

我的Android开发遇到了一个令人生气的问题 - 每当我调用startActivityForResult(this, Notepadv3.class);时,我的应用程序直接跳过它,不会启动新活动,也不会从中返回任何结果。好像代码不在那里!

当我将this更改为mContext时(我在课程开头将mContext定义为Context mContext;),应用程序崩溃了NullPointerException

我在不同的类中使用了完全相同的代码布局,并且运行完美。 我已经确认我正在宣布清单中的活动。

我花了几个小时搜索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:

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");
    }
}

}

2 个答案:

答案 0 :(得分:1)

首先,如果你使用mContext,你应该在onCreate方法中初始化它:

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

不要从onPause方法启动一个Activity。

答案 1 :(得分:0)

我修好了!!!

对于大多数正在寻找答案的人来说,这不是一个解决办法,但我希望我能指出你正确的方向。我和Android(以及一般的Java)一样新,我仍然完全相信这种“跳过”代码实际上是一个错误。

然而!当我从另一个活动中调用saveState()时,不是启动一个新的意图,从一个单独的类启动一个活动,然后从第一个意图来自的类启动一个活动,我只需用{替换它{1}}。是的 - 学习逻辑还是很狡猾,但事实确实如此。简单,优雅,解决方案(与之前存在的可怕代码相比,简单而优雅:P)