Android学习第十篇——startActivityForResult和handle

作为一名准大四的学生,本来开始在准备做毕业设计了,可是遇到了一个瓶颈,所以趁着这空隙再夯实一下基础,今天要讲的是 startActivityForResult    (handle -- looker -- message queue) 


Part 1.  startActivityForResult

首先来理解一下这是干嘛的,看意思是“启动一个活动为了结果”,直白的讲就是在一个Activity中得到新打开的Activity关闭后的返回的数据,这个时候我们就需要用到startActivityForResult。那接下来我们就具体来讲讲这个方法
public void startActivityForResult (Intent intent, int requestCode)

Parameters

intent	The intent to start.
requestCode	If >= 0, this code will be returned in onActivityResult() when the activity exits.
       我们可以看到这是一个需要两个参数的方法,第一个参数Intent,这个就是我们要新打开的那个Activity,第二个参数是一个请求码,并且这个请求码是>=0的一个int型的参数。可能在这里会产生一个疑惑,这个请求码是干嘛的,第一个参数应该不用多讲了,那么我们就这个请求码来具体的讲一下吧。 请求码的值是根据业务需要由自已设定,用于标识请求来源,我们可以设想那么一种情况,在一个Activity01(启动页,即最开始显示的页面),在这个页面上我们放置了两个Button(button01和button02),而点击这两个Button都会跳转到同一个Activity02上(使用startActivityForResult),那么我们就不知道,到底是点击哪个按钮之后才跳转到Activity02的,而我们设置了请求码之后,我们就可以根据我们的请求码得到是点击哪个按钮跳转过来的,这样我们在处理结果的时候也会很方便。

讲到处理结果,也许又要产生疑惑了,我们要在哪里处理结果呢??
当我们使用startActivityForResult这个方法后,我们还需要重写一下onActivityResult这个方法,这个方法的作用就是当新的Activity关闭后处理返回的结果。
protected void onActivityResult (int requestCode, int resultCode, Intent data) 

Parameters
requestCode  The integer request code originally supplied to startActivityForResult(), 
allowing you to identify who this result came from. 
resultCode  The integer result code returned by the child activity through its setResult(). 
data  An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). 

这个方法有三个参数,第一个参数就是我们之前讲的请求码,第二个参数是结果码,第三个参数是返回的结果数据,请求码和结果码有n-->1 和 1-->1 这样的可能(这是我自己的理解,不知道对不对,如果有问题,请留言,我马上纠正),这里我讲一下我的理解,1-->1的情况我就不多讲,讲讲n-->1,就像上面说的,当一个页面上存在多个按钮,并且这多个按钮都打开同一个Activity,那么这个页面关闭的时候,返回的结果码就只要一个了,这样就是n-->1了,那可不可能存在n-->n呢??这种情况其实就是已经包含在上面两种里了,n个结果码,来自于n个Activity中,而每一个Activity可以由1个按钮打开或者多个按钮打开,这样就又回到了上面的情况了。

接下来我们来看点例子!

例1:两个按钮打开同一个Act ivity,产生两个requestCode

 @Override  public void onCreate(Bundle savedInstanceState) {
        ....
        button1.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 1);

           }

        });
        button2.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                 startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2);

            }

        }); 


       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
               switch(requestCode){
                   case 1:
                   //来自按钮1的请求,作相应业务处理
                   case 2:
                   //来自按钮2的请求,作相应业务处理
                }
          }
}


例2:从Activity01打开两个Activity(Activity02和Activity03),返回了两个resultCode

public class Activity02 extends Activity {
       .....
       Activity02.this.setResult(1, intent);
       Activity02.this.finish();
}
public class Activity03 extends Activity {
       ......
        Activity03.this.setResult(2, intent);
        Activity03.this.finish();
}
public class Activity01 extends Activity { // 在该Activity会打开Activity02和Activity03
       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
               switch(resultCode){
                   case 1:
                   // Activity02的返回数据
                   case 2:
                    // Activity03的返回数据
                }
          }
} 


接下来我们来看一个完整的例子

例3:

主页布局main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A1" >
    </Button>

</LinearLayout>

新打开Activity的布局activity1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:id="@+id/Button02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Main" >
    </Button>

</LinearLayout>


Main. java
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button btn=(Button)findViewById(R.id.Button01);
        btn.setOnClickListener(
        		new OnClickListener() {
					public void onClick(View arg0) {
						Intent intent=new Intent(Main.this,Activity1.class);
						Bundle bundle=new Bundle();
						bundle.putString("username","lxt008");
						bundle.putInt("age",100);
						intent.putExtras(bundle);
						startActivityForResult(intent, 1);						
					}
				}
        );
    
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    	Log.v("Main", ""+requestCode);
    	Log.v("Main", ""+resultCode);
    	Log.v("Main", data.getExtras().getString("address"));
    }

Activity1.java

	@Override
	protected void onCreate(Bundle savedInstanceState) {		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity1);
		Log.v("Activity1", "onCreate()");
		
		Bundle bundle=this.getIntent().getExtras();
		Log.v("Activity1", bundle.getString("username"));
		Log.v("Activity1", ""+bundle.getInt("age"));
		
		Button btn=(Button)findViewById(R.id.Button02);
	        btn.setOnClickListener(
	        		new OnClickListener() {
						
						public void onClick(View arg0) {
							
							Intent intent=new Intent(Activity1.this,Main.class);
							startActivity(intent);
							
							Activity1.this.finish();
						}
					}
	        );
	        
	     Intent intent=new Intent();
	     intent.putExtra("address", "sz");
	     this.setResult(3, intent);
	     this.finish();
	}

运行界面图
,界面上一个按钮,点击这个按钮之后会跳转到Activity1.java中,但是在这里我们不会看到Activity1.java,看代码中就会明白了。

我们看一下logcat的打印结果


这部分就讲到这里了!


Part 2. handler -- looper -- messageQueue


以下这部分文字复制自上面的文章

Message Queue 

    在单线程模型下,为 了解决类似的问题,Android设 计了一个Message Queue(消息队列), 线程间可以通过该Message Queue并结合Handler和Looper组 件进行信息交换。 
l  Message Queue 

     Message Queue是一个消息队列,用来存放通过Handler发 布的消息。消息队列通常附属于某一个创建它的线程,可以通过Looper.myQueue()得 到当前线程的消息队列。如果没有消息队列对象则会抛出空指针异常 。Android在 第一次启动程序时会默认会为UI thread创建一个关联的消息队列,用来管理程序的一些上层组件,activities,broadcast receivers 等等。你可以在自己的子线程中创建Handler与UI thread通讯。也就是说我们程序一启动我们的UI线程也就是主线程就会有一个消息队列 ,而如果我们自己另外开启的一个子线程就不会有MessageQueue(消息队列)对象。这一点大家务必知道。 

l  Handler 

    通过Handler你 可以发布或者处理一个消息或者是一个Runnable的 实例。每个Handler都 会与唯一的一个线程以及该线程的消息队列关联。当你创建一个新的Handler时候,默认情况下,它将关联到创建它的这个线程和该线程的消息队列。也就是说,如果你通过Handler发 布消息的话,消息将只会发送到与它关联的这个消息队列,当然也只能处理该消息队列中的消息。这里大家就得理解一下了 也就是说我们 一个Handler对应一个线程以及附属于该线程的消息队列。就比如 我们现在有一个Handler对象这个Handler在UI线程中创建 叫xh_Handler 那么我们根据上边的说明 应该可以告诉我 这个xh_Handler是和那个线程关联的?  如果我用这个Handler发消息的话它将发给那个线程的消息队列? 如果你知道了 我想一般情况下你肯定是知道的。说明你很懂。我们继续。这时我们用这个Handler对象发送消息 
Handler对象也可以发送消息哦,它有发送消息的方法。下面就说到了 待会大家看示例程序也会发现 主要就是看它怎么使用。 

Handler的主要的方法有: 

1)   public final boolean sendMessage(Message msg) 

把消息放入该Handler所 关联的消息队列,放置在消息队列尾部。 
2)   public void handleMessage(Message msg) 

    关联该消息队列的线 程将通过调用Handler的handleMessage方 法来接收和处理消息,通常需要子类化Handler来 实现handleMessage。 

l  Looper 

Looper扮演着一个Handler和 消息队列之间通讯桥梁的角色。程序组件首先通过Handler把 消息传递给Looper,Looper把 消息放入队列。Looper也 把消息队列里的消息广播给所有的Handler,Handler接 受到消息后调用handleMessage进 行处理。 

1)   可以通过Looper类 的静态方法Looper.myLooper得 到当前线程的Looper实 例,如果当前线程未关联一个Looper实 例,该方法将返回空(null)它不会抛空指针异常。 

2)   可以通过静态方法Looper. getMainLooper方法得到主线程的Looper实 例 这里需要注意一下 主线程默认是有一个Looper对象的。但是我们自己定义的子线程没有的。那么我们怎么在子线程中得到Looper对象呢?如果一个线程中调用Looper.prepare(),那么系统就会自动的为该线程建立一个消息队列,然后调用 Looper.loop();之后就进入了消息循环,这个之后就可以发消息、取消息、和处理消息。这个如何发送消息和如何处理消息可以再其他的线程中通过 Handle来做,但前提是我们的Hanle知道这个子线程的Looper,但是你如果不是在子线程运行 Looper.myLooper(),一般是得不到子线程的looper的。 

代码部分我就不贴了,看文章自己敲一下或者下载我的代码参考,接着我就分享一下我学习过程中的一些收获

1>  Message message =myHandler.obtainMessage();
可能之前我们还看到过这样的 Message message = new Message();
这里讲一下两者。
Message message = new Message();这个是在内存中创建一个新的对象,
而第一个则是从
 * 从整个 Message Pool 中返回一个新的Message实例,
* 在许多情况下使用它,因为它能避免分配新的对象
* 如果是这样的话,那么通过调用obtainMessage方法获取Message对象就能避免创建对象,
* 从而减少内存的开销了。主要是在对象的创建的时候的减少

2> 看了代码后,你会看到这里有两种使用Thread的方法,
一种是直接
new Thread(){},
还有一种是 
Runnable r = new Runnable(){}; 
Thread thread = new Thread(r);
Runnable是一个接口,ThreadRunnable的子类。

写到这以后,发现有点写不下去了,因为感觉自己对这些的理解还不够,这次的笔记就到这了,等我闭关修炼一段时间在继续。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值