Android 代码用来返回上一个activity 调用onKeyDown()时发生java.lang.NullPointerException.

来自:CSDN博客推荐文章   |  时间:2012-05-04 22:42:12

原文链接: 

很多人想从一个Activity返回到上一级Activity时,考虑通过在点击事件里调用OnKeyDown事件来返回上一级,如下:

toolbarBack.setOnClickListener(newOnClickListener(){@Overridepublicvoid onClick(View v){OnKeyDown(KeyEvent.KEYCODE_BACK,null);}});

会发现报空指针错误,具体原因看下源码,你没传入的参数(即null)在OnKeyDown方法中使用到了,所以空指针。

其实返回上一级,不用考虑如此复杂,我们可以使用如下:直接结束当前Activity不就行了。测试可用

toolbarBack.setOnClickListener(newOnClickListener()
{@Overridepublicvoid onClick(View v){
ReaderActivity.this.finish();
   }
});

注意:

要在第一个activity向第二个activity跳转的时候将第一个activity finish(),这样在第二个activity返回第一个activity时,就会执行第一个activity的onCreate()方法。
我尝试着在第一种方法中使用如下:
toolbarBack.setOnClickListener(newOnClickListener(){@Overridepublicvoid onClick(View v){OnKeyDown(KeyEvent.KEYCODE_BACK,newKeyEvent(KeyEvent.KEYCODE_BACK,KeyEvent.ACTION_DOWN));}});
虽说无空指针错误,但是没任何效果。我也不解,望知情的兄弟告知一声哈!

下面我再贴一些其他的 方法

Android实战总结之返回键返回上一级Activity(Intent的一种用法)

 

实现功能: 有两个Activity,一个为tabActivity,一个为EditActivity,tabActivity进入EditActivity后,在EditActivity中单击返回键返回tabActivity.

其实很简单,这其中涉及到onKeyDown(),和Intent。

只要在EditActivity中重写onKeyDown()实现捕获返回键,再加一Intent实现Activity的跳转。

具体实现:

 

1

2

3

4

5

6

7

8

9

10

11


@Override

public boolean onKeyDown(int keyCode, KeyEvent event)

{

if(keyCode == KeyEvent.KEYCODE_BACK){

Intent myIntent = new Intent();

myIntent = new Intent(EditActivity.this, tabActivity.class);

startActivity(myIntent);

this.finish();

}

return super.onKeyDown(keyCode, event);

}


3.在A中用startActivityForResult(Intent intent,int requestcode)启动B,值得注意的是requestcode里的值在多个Activity时使用Reuest_OK,无法从B返回到a的onActivityResult。
重写A的onActivityResult(int requestCode, int resultCode, Intent data),B在返回前使用setResult(int resultCode,Intent data)设置返回的数据,最后调用b的finish后会返回A的onActivityResult方法。
看例子

3.11 返回数据到前一个Activity

startActivityForResult方法

范例说明

上一个范例中,好不容易将数据从Activity1传递至Activity2,如果要再回到Activity1,数据该不会要再封装一次吧?而且前一个Activity1早就被程序destroy了,倘若在Activity1最后以finish() 结束程序,再通过Activity2将数据采用Bundle的方式通过新打开Activity1传递参数,这样的做法虽然也可以恢复User输入的数据,但是并不符合我们的期待,尤其是User曾经输入过的数据,如果不小心点击回到上一页,数据就消失不见,这就不妙了。

有鉴于科技始终来自于人性,如果要在次页面加上一个"回上页"的按钮,而非通过模拟器的回复键,且回上页后又能保留之前输入的相关信息,那么就必须使用startActivityForResult()来唤起一个Activity。利用这个方法,前一个Activity1便会有一个等待次Activity2的返回,而返回的数据就可以达到我们想要的结果。

运行结果

 

(点击查看大图)图3-11  将数据返回到前一个Activity

范例程序

  1. src/irdc.ex03_11/EX03_11.java 

在Activity1主程序中调用Activity的方法更改成startActivityForResult(intent,0),其中0为下一个Activity要返回值的依据,可指定为自行定义的参考标识符(Identifier)。程序覆盖了onActivityResult() 这个方法,令程序在收到result后,再重新加载写回原本输入的值。

    1. package irdc.ex03_11;  
    2.  
    3. /* import相关class */ 
    4. import android.app.Activity;  
    5. import android.content.Intent;  
    6. import android.os.Bundle;  
    7. import android.view.View;  
    8. import android.widget.Button;  
    9. import android.widget.EditText;  
    10. import android.widget.RadioButton;  
    1. 11.  
    12. public class EX03_11 extends Activity   
    13. {  
    1. 14.   private EditText et;  
    2. 15.   private RadioButton rb1;  
    3. 16.   private RadioButton rb2;  
    4. 17.       
    5. 18.   /** Called when the activity is first created. */ 
    6. 19.   @Override 
    7. 20.   public void onCreate(Bundle savedInstanceState)   
    8. 21.   {  
    9. 22.     super.onCreate(savedInstanceState);  
    10. 23.     /* 载入main.xml Layout */ 
    11. 24.     setContentView(R.layout.main);  
    12. 25.       
    13. 26.     /* 以findViewById()取得Button对象,并添加onClickListener */ 
    14. 27.     Button b1 = (Button) findViewById(R.id.button1);  
    15. 28.     b1.setOnClickListener(new Button.OnClickListener()  
    16. 29.     {  
    17. 30.       public void onClick(View v)  
    18. 31.       {  
    19. 32.         /*取得输入的身高*/ 
    20. 33.         et = (EditText) findViewById(R.id.height);  
    21. 34.         double height=Double.parseDouble(et.getText().toString());  
    22. 35.         /*取得选择的性别*/ 
    23. 36.         String sex="";  
    24. 37.         rb1 = (RadioButton) findViewById(R.id.sex1);  
    25. 38.         rb2 = (RadioButton) findViewById(R.id.sex2);  
    26. 39.         if(rb1.isChecked())  
    27. 40.         {  
    28. 41.           sex="M";  
    29. 42.         }  
    30. 43.         else 
    31. 44.         {  
    32. 45.           sex="F";  
    33. 46.         }      
    34. 47.           
    35. 48.         /*new一个Intent对象,并指定class*/ 
    36. 49.         Intent intent = new Intent();  
    37. 50.         intent.setClass(EX03_11.this,EX03_11_1.class);  
    38. 51.           
    39. 52.         /*new一个Bundle对象,并将要传递的数据传入*/ 
    40. 53.         Bundle bundle = new Bundle();  
    41. 54.         bundle.putDouble("height",height);  
    42. 55.         bundle.putString("sex",sex);  
    43. 56.         
    44. 57.         /*将Bundle对象assign给Intent*/ 
    45. 58.         intent.putExtras(bundle);  
    46. 59.         
    47. 60.         /*调用Activity EX03_11_1*/ 
    48. 61.         startActivityForResult(intent,0);  
    49. 62.       }  
    50. 63.     });  
    51. 64.   }  
    52. 65.     
    53. 66.   /* 覆盖 onActivityResult()*/ 
    54. 67.   @Override 
    55. 68.   protected void onActivityResult(int requestCode, int resultCode,  
    56. 69.                                   Intent data)  
    57. 70.   {  
    58. 71.     switch (resultCode)  
    59. 72.     {   
    60. 73.       case RESULT_OK:  
    61. 74.         /* 取得来自Activity2的数据,并显示于画面上 */    
    62. 75.         Bundle bunde = data.getExtras();  
    63. 76.         String sex = bunde.getString("sex");  
    64. 77.         double height = bunde.getDouble("height");  
    65. 78.           
    66. 79.         et.setText(""+height);  
    67. 80.         if(sex.equals("M"))  
    68. 81.         {  
    69. 82.           rb1.setChecked(true);  
    70. 83.         }  
    71. 84.         else 
    72. 85.         {  
    73. 86.           rb2.setChecked(true);  
    74. 87.         }  
    75. 88.         break;  
    76. 89.       default:  
    77. 90.         break;  
    78. 91.      }   
    79. 92.    }   
    93. }

    src/irdc.ex03_11/EX03_11_1.java

    在Activity2的主程序中,设计当Button被点击时,将Bundle对象与结果返回给前一个Activity1。

      1. package irdc.ex03_11;  
      2.  
      3. /* import相关class */ 
      4. import java.text.DecimalFormat;  
      5. import java.text.NumberFormat;  
      6. import android.app.Activity;  
      7. import android.content.Intent;  
      8. import android.os.Bundle;  
      9. import android.view.View;  
      10. import android.widget.Button;  
      11. import android.widget.TextView;  
      1. 12.  
      13. public class EX03_11_1 extends Activity   
      14. {  
      1. 15.   Bundle bunde;  
      2. 16.   Intent intent;  
      3. 17.   /** Called when the activity is first created. */ 
      4. 18.   @Override 
      5. 19.   public void onCreate(Bundle savedInstanceState)   
      6. 20.   {  
      7. 21.     super.onCreate(savedInstanceState);  
      8. 22.     /* 载入mylayout.xml Layout */ 
      9. 23.     setContentView(R.layout.myalyout);  
      10. 24.       
      11. 25.     /* 取得Intent中的Bundle对象 */ 
      12. 26.     intent=this.getIntent();  
      13. 27.     bunde = intent.getExtras();  
      14. 28.       
      15. 29.     /* 取得Bundle对象中的数据 */ 
      16. 30.     String sex = bunde.getString("sex");  
      17. 31.     double height = bunde.getDouble("height");  
      18. 32.       
      19. 33.     /* 判断性别 */ 
      20. 34.     String sexText="";  
      21. 35.     if(sex.equals("M"))  
      22. 36.     {  
      23. 37.       sexText="男性";  
      24. 38.     }  
      25. 39.     else 
      26. 40.     {  
      27. 41.       sexText="女性";  
      28. 42.     }  
      29. 43.       
      30. 44.     /* 取得标准体重 */ 
      31. 45.     String weight=this.getWeight(sex, height);  
      32. 46.       
      33. 47.     /* 设置输出文字 */ 
      34. 48.     TextView tv1=(TextView) findViewById(R.id.text1);  
      35. 49.     tv1.setText("你是一位"+sexText+"\n你的身高是"+height+  
      36. 50.                    "厘米\n你的标准体重是"+weight+"公斤");  
      37. 51.       
      38. 52.     /* 以findViewById()取得Button对象,并添加onClickListener */ 
      39. 53.     Button b1 = (Button) findViewById(R.id.button1);  
      40. 54.     b1.setOnClickListener(new Button.OnClickListener()  
      41. 55.     {  
      42. 56.       public void onClick(View v)  
      43. 57.       {            
      44. 58.         /* 返回result回上一个activity */ 
      45. 59.         EX03_11_1.this.setResult(RESULT_OK, intent);  
      46. 60.           
      47. 61.         /* 结束这个activity */ 
      48. 62.         EX03_11_1.this.finish();  
      49. 63.       }  
      50. 64.     });  
      51. 65.   }  
      52. 66.     
      53. 67.   /* 四舍五入的method */ 
      54. 68.   private String format(double num)  
      55. 69.   {  
      56. 70.     NumberFormat formatter = new DecimalFormat("0.00");  
      57. 71.     String s=formatter.format(num);  
      58. 72.     return s;  
      59. 73.   }  
      60. 74.  
      61. 75.   /* 以findViewById()取得Button对象,并添加onClickListener */    
      62. 76.   private String getWeight(String sex,double height)  
      63. 77.   {  
      64. 78.     String weight="";  
      65. 79.     if(sex.equals("M"))  
      66. 80.     {  
      67. 81.       weight=format((height-80)*0.7);  
      68. 82.     }  
      69. 83.     else 
      70. 84.     {  
      71. 85.       weight=format((height-70)*0.6);  
      72. 86.     }    
      73. 87.     return weight;  
      74. 88.   }  
      89. }

      res/layout/mylayout.xml

      mylayout.xml为Activity2(EX03_11_1)的Layout,其中定义了显示计算结果的TextView与回上一页的Button按钮。

        1. <?xml version="1.0" encoding="utf-8"?>  
        2. <AbsoluteLayout  
        3.   android:layout_width="fill_parent" 
        4.   android:layout_height="fill_parent" 
        5.   xmlns:android="http://schemas.android.com/apk/res/android" 
        6. >  
        7.   <TextView  
        8.     android:id="@+id/text1" 
        9.     android:layout_width="wrap_content" 
        10.     android:layout_height="wrap_content" 
        11.   android:textSize="20sp" 
        12.     android:layout_x="50px" 
        13.     android:layout_y="72px" 
        14.   >  
        15.   </TextView>  
        16.   <Button  
        17.     android:id="@+id/button1" 
        18.     android:layout_width="100px" 
        19.     android:layout_height="48px" 
        20.     android:text="回上一页" 
        21.     android:layout_x="110px" 
        22.     android:layout_y="180px" 
        23.   >  
        24.   </Button>  
        25. </AbsoluteLayout>

        AndroidManifest.xml

        范例中有两个Activity,所以AndroidManifest.xml里必须有这两个activity的声明,否则系统将无法运行。

          1. <?xml version="1.0" encoding="utf-8"?>  
          2. <manifest  
          3.   xmlns:android="http://schemas.android.com/apk/res/android" 
          4.   package="irdc.ex03_11" 
          5.   android:versionCode="1" 
          6.   android:versionName="1.0.0">  
          7.   <application  
          8.     android:icon="@drawable/icon"   
          9.     android:label="@string/app_name">  
          10. 10.     <activity  
          11. 11.       android:name=".EX03_11" 
          12. 12.       android:label="@string/app_name">  
          13. 13.       <intent-filter>  
          14. 14.         <action android:name="android.intent.action.MAIN" />  
          15. 15.         <category android:name="android.intent.category.LAUNCHER" />  
          16. 16.       </intent-filter>  
          17. 17.     </activity>  
          18. 18.     <activity android:name="EX03_11_1"></activity>  
          19. 19.   </application>  
          20. </manifest>

          扩展学习

          范例中为了在回到上一页时,能够显示之前所输入的数据,故将原本传递次Activity的Intent(里面包含了有数据的Bundle对象)再重新返回给主Activity1。如果要在次Activity2中返回其它的数据,例如,经过计算后的结果、数据,此时只需将要返回的数据再放入Bundle对象中即可达成。

          此外,以本范例而言,其实使用startActivity()也可达成同样的结果,仅需在主Activity被create时去判断Intent内有没有数据,有的话,就将数据带入;没有的话,就带入空值(null)。但程序还需要再做有无值的比较,较为繁琐,既然Android API中有提供更好用的方法,何来不用的道理?更何况如果系统不是只有几行代码,而是几十行、几百行代码,那时头可就大了!