Intent的用法 - Android学习笔记2

Intent的用法


一、简介:

    

     1. Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件

           想要执行的动作,还可以在不同的组件之间传递数据。

 

     2. Intent一般可以被用于启动活动、传递数据、启动或停止服务、以及发送广播等场景。


二、Intent的基本使用:

   1. 启动活动:

     1). 启动活动有2种方式:显示Intent与隐式Intent;俩者的区别:

  
         简单的说:
         ①.对于明确指出了目标组件名称的Intent,我们称之为“显式Intent”。
         ②.对于没有明确指出目标组件名称的Intent,则称之为“隐式Intent”。
  
         作用范围:
         ①.显式Intent直接用组件的名称定义目标组件,这种方式很直接,
              但是你必须很明确的知道你所调用的目标组件的名称与功能,
              因此,显式Intent更多用于在应用程序内部传递消息(自己的程序你知道哪部分在做什么) 

             比如在某应用程序内,一个Activity启动一个Activity或Service。           

       ②. 但如果想调用别的程序的组件时,且开发人员往往并不清楚别的应用程序的组件名称,
             这时我们只能用隐式Intent,隐式Intent恰恰相反,它不会用组件名称定义需要激活的目标组件,
             而是Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。
             Android系统具体怎么找:主要是通过Intent Filter来寻找与隐式Intent相关的对象。
             (更详细的另一篇《隐式Intent的使用》中细说)

             因此,隐式Intent更广泛地用于在不同应用程序之间传递消息。


       2). 使用显示的Intent: 

/*
 *FirstActivity 来启动 SecondActivity
 *  FirstActivity.this作为上下文传入;(随时获取上下文的方法在《Toast》中提过)
 *  SecondActivity.class作为目标活动(目标组件)传入->明确指出,所以为显示Intent
 *  startActivity()用于启动活动
 */
   Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
   intent.startActivity(intent);

       

      3).使用隐式的Intent:

     
          ①.在AndroidManifest.xml中定义<intent-filter>(位于<activity>内部):
<!--1.这里定义了目标活动(目标组件) -> .SecondActivity-->
<!--2.指明这个活动的【动作标识action为】:com.example.activity.ACTION_START-->
<!--3.指明这个活动的【类别标识category为】:android.intent.category.DEFAULT 与-->
                                        <!--com.example.activity.CPJ_category-->
										
        <activity android:name="com.example.activity.SecondActivity">
            <intent-filter>                
                <action android:name="com.example.activity.ACTION_START"/>                              
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.example.activity.CPJ_category"/>
            </intent-filter>
        </activity>
		
<!--指定当前活动可以响应com.example.activity.ACTION_START这个action-->
<!--1.<category>标签包含一些附加信息,更精确指明当前的活动能够响应的Intent中,还可能带有的category-->
<!--2.只有action和category同时匹配才能响应Intnet-->                   
<!--3.android.intent.category.DEFAULT是一种默认的category,在调用-->
<!--startActivity()时会自动把这个category添加到intent中-->                    
<!--4.一个intent只能由一个action,但是可以有多个category-->  

         ②.定义跳转的上下文FirstActivity.java,并在其中加入如下代码:

 /*
  *FirstActivity 来启动 SecondActivity
  *  new Intent("com.example.activity.ACTION_START")定义了动作标识action
  *  addCategory("com.example.activity.CPJ_category")定义了类别标识category
  *  startActivity()用于启动活动
  *此时安卓系统会寻找将action与category都匹配上的目标组件,正好会匹配上
  *我们前面定义的.SecondActivity,所以会启动SecondActivity活动。
  *  以下代码,并没有明确指出目标组件,而是去匹配,所以称为隐式Intent
  */
 Intent intent = new Intent("com.example.activity.ACTION_START");
   intent.addCategory("com.example.activity.CPJ_category");
   intent.startActivity(intent);

     2.传递数据:  

      
      Intent还可以在启动一个活动的同时传递一些数据给它(FirstActivity传值给SecondActivity):
 

     1). FirstActivity中加入如下代码:

 
   /*
    * 向下一个活动传递参数,利用Intent的putExtra()把信息暂时存储在缓冲中
    *   putExtra()参数为键值形式:第一个参数是键,第二个参数是值,
    */
    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
      intent.putExtra("extra_data1","Hello SecondActivity");//传一个String型
      intent.putExtra("extra_data2",100);//再传一个int型
    startActivity(intent);
</pre><span style="white-space:pre"></span><h3>      <span style="font-weight:normal; background-color:rgb(255,255,255)"><span style="font-size:14px; color:#cc33cc">2). SecondActivity中加入如下代码:</span></span></h3><span style="white-space:pre"></span> <pre name="code" class="java">/*
 * SecondActivity来接收传来的参数:
 *   getStringExtra()接收传来的String型参数
 *   getIntExtra()接收传来的Int型参数,如果没值时返回0
 */
   Intent intent = getIntent();
   String string_data = intent.getStringExtra("extra_data1");
   String int_data = intent.getIntExtra("extra_data2", 0);

      我们会发现putExtra()所支持的类型是有限的,虽然常用的一些类型都能传递,但是如果想
      传递一个自定义的对象时,就做不到了。使用Intent传递对象的方法在下下篇
    《使用Intent传递对象》中详细介绍。


     利用Intent返回数据给上一个活动(SecondActivity在销毁时传值给FirstActivity):
     
     1). FirstActivity中写入如下代码(利用startActivityForResult()启动活动):

/*
 * startActivityForResult用于启动活动,但这个方法期望在活动销毁的时候能够返回一个结果给
 *     上一个活动。有2个参数:
 * 第一个参数:Intent
 * 第二个参数:请求码,用于在之后的判断中判断数据的来源
 * */
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);

      2). SecondActivity中写入如下代码(执行销毁操作,并传数据给Intent缓冲): 
 
/*
 * setResult()方法接收俩个参数,
 *   第一个参数:用于向上一个活动返回处理数据,一般是RESULT_OK与RESULT_CANCELED这俩个值
 *   第二个参数:则是把带着数据的intent传递回去
 * */
Intent intent = new Intent();
  intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK, intent);
finish();//销毁SecondActivity

    3).FirstActivity中写入如下代码(重写onActivityResult()方法):
 
/**
 * 接收上一个销毁的活动的值(由startActivityResult()启动的活动,会在销毁时,回调上一个活动的onActivityResult())
 * @param {int} requestCode 启动活动时传入的请求码(1)
 * @param {int} resultCode 返回数据时传入的处理结果集
 * @param {Intent} data 带着数据的intent
 * */
public void onActivityResult(int requestCode, int resultCode, Intent data){
	switch (requestCode){
		case 1:
			if(resultCode == RESULT_OK){
				String returnedData = data.getStringExtra("data_return");
				Log.d("FirstActivity", returnedData);
			}
			break;
		default:
	}
}

    3.启动或停止服务:


       利用主活动MainActivity去启动或停止一个自定义服务MyService
 

       1).MainActivity中写入如下代码:

 
/*
 *启动一个服务:
 *  MainActivity.this为上下文
 *  MyService.class为目标服务(目标组件) -> 显示Intent调用
 *  startService()启动服务
 */
Intent startIntent = new Intent(MainActivity.this, MyService.class);
  startService(startIntent);
  
/*
 *停止一个服务:
 *  MainActivity.this为上下文
 *  MyService.class为目标服务(目标组件) -> 显示Intent调用
 *  stopService()停止服务
 */
Intent stopIntent = new Intent(MainActivity.this, MyService.class);
  stopService(stopIntent);

      2).那么能隐式的调用Service吗?


            答案是:可以,但不同于隐式调用Activity;
 
        如果你像前面一样这样写到:
         Intent startIntent = new Intent("com.example.cpj.Service.action_MyService");
           startIntent.addCategory("com.example.cpj.Service.service_category");
           startService(startIntent);//启动服务

        就汇报:Service Intent must be explicit 的错误!


       原因是:
        Android 5.0一出来后,其中有个特性就是Service Intent  must be explitict,
       也就是说从Lollipop开始,service服务必须采用显示方式启动。
  
       那如何隐式调用服务呢:
       方法:设置Action和packageName:

      ①. 在AndroidManifest.xml中定义<intent-filter>(位于<service>内部):

 
 <!--服务注册-->
<service android:name="com.example.cpj.Service.MyService">
<intent-filter>
<action android:name="action_MyService"/>
<category android:name="category_MyService"/>
</intent-filter>
</service>

           
        ②. 在MainActivity中写入如下代码:
 Intent startIntent = new Intent();
   startIntent.setPackage(getPackageName());//这里你需要设置你应用的包名
   startIntent.setAction("action_MyService");//action
   startIntent.addCategory("service_category");//category
startService(startIntent);//启动服务

    4.发送广播:


      利用主活动MainActivity去发送一个自定义广播MyBroadcastReceiver

     ①.在AndroidManifest.xml中定义<intent-filter>(位于<receiver>内部):

<!--服务注册-->
<receiver android:name="com.example.cpj.MyBroadcastReceiver">
<intent-filter>
<action android:name="MY_BROADCAST"/>
</intent-filter>
</receiver>

       ②.在MainActivity中写入如下代码:
Intent intent = new Intent("MY_BROADCAST");
sendBroadcast(intent);

  三、Intent的隐式用法

     Intent的隐式用法也很丰富,比如调用打电话、发短信、开网页等功能;

    这些内容都在下一篇《隐式Intent的使用》中具体说明;















    

你可能感兴趣的:(android,intent)