Android-活动(Activity)Intent

稍微正常点的应用都应该不只有一个活动,通常都是有成打的活动,然后通过各种事件进行跳转。连接起各种活动的桥梁,就是所谓的Intent。

什么是Intent?

Intent是Android用来连接各个组件并且将组件进行j解耦的重要组件,比如指明当前组件的意图,或者在组件之间传递数据。

Intent相当于一个媒婆,为两个组件牵线搭桥,并且为他们之间的信息交换提供了渠道。比如,有一个人(Activity)想找个白富美当老婆,他把这个“意图”写在了脸上,然后让媒婆(Intent)去找找看,有没有这么个人是符合要求的。媒婆找了找,还真有一个符合条件的人,然后就把这俩人介绍到一起,并且为对方提供他们想了解的数据。

Intent也分为两种:显式Intent(点名道姓)和隐式Intent(条件筛选)。我们一个一个说。

显式Intent

首先上代码:

因为我们要实现Activity的跳转,所以我们要建立两个活动才行:

 1 public class FirstActivity extends AppCompatActivity  //第一个活动
 2 {
 3 
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState)
 6     {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9         Button button1 = (Button) findViewById(R.id.button_1);
10         button1.setOnClickListener(new View.OnClickListener()
11         {
12             @Override
13             public void onClick(View v)
14             {
15                 Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
16                 startActivity(intent);
17             }
18         });
19     }
20 }
 1 public class SecondActivity extends AppCompatActivity  //第二个活动
 2 {
 3 
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState)
 6     {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_second);
 9     }
10 }

第一个活动对应的布局文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent">
 4 
 5     <Button
 6         android:id="@+id/button_1"
 7         android:layout_width="wrap_content"
 8         android:layout_height="wrap_content"
 9         android:text="This is Button 1" />
10 </LinearLayout>

第二个布局文件没写什么,就不放上来了。

我们分析下代码:

FirstActivity在Button的点击事件中定义了一个Intent(媒婆),这个Intent有很多构造函数的重载,我们这里使用的是

Intent(Context packageContext,Class<?> cls);

这里我们要传入两个参数:第一个是这个启动活动的上下文(上下文的解释看上一篇),第二个是我们这个Intent的“意图”,也就是我们这个Intent想跳转到哪里。但是我们要注意,第一个传入的是对象(.this),第二个是.class,传入类文件之后,虚拟机会自动装载类文件。

接下来,我们的Intent已经准备妥当,我们还需要去启动Intent。使用startActivity(Intent intent),传入我们的Intent就可以发动“媒婆”,启动目标活动了。

隐式Intent

显示Intent好比是指明了要志玲做老婆,点名道姓,意图明显。而隐式Intent,是规定了条件,只有符合条件的才能被我接纳。

要想能匹配得上,有两部分要完全相同:action和category。

废话不多说,上代码,首先是AndroidMainifest.xml(只贴出修改部分)

1 <activity android:name=".SecondActivity">
2     <intent-filter>
3         <action android:name=".ACTION_START" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 我们修改了SecondActivity的标签,为它加入了action和catagory标签。action标签说明了我们这个活动可以响应哪个action。action表明了我们这个活动可以执行的动作,可以使用系统提供的(比如拨号ACTION_CALL),也可以自己定义。这里我们是自己定义的;catagory包含了更加细节的一些信息。

然后我们修改FirstActivity.java的代码

 1 public class FirstActivity extends AppCompatActivity
 2 {
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState)
 5     {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_main);
 8         Button button1 = (Button) findViewById(R.id.button_1);
 9         button1.setOnClickListener(new View.OnClickListener()
10         {
11             @Override
12             public void onClick(View v)
13             {
14                 Intent intent = new Intent(".ACTION_START");
15                 startActivity(intent);
16             }
17         });
18     }
19 }

我们修改了Intent的构造函数,直接传入了action的字符串,表明我们想启动能响应.ACTION_START这个action的活动。但是,我们在这里并没有出现于category的相关声明,是怎么回事呢?

因为我们给SecondActivity传入的是"android.intent.category.DEFAULT"这个参数,这是一个默认的catgory,在我们startActivity时会自动调用这个参数到我们的intent中。

我们启动程序,效果与刚才的是一样的。

当然,我们也可以指定多个category,但是只能有一个action。

1 intent.addCategory(".MY_CATEGORY1");
2 intent.addCategory(".MY_CATEGORY2");

这样就可以为我们的intent添加category了。

但是我们的所有活动里面必须有一个是能响应你这个intent的,否则程序会崩溃。

 

隐式Intent的更多用法

我们在平时使用别人家的app时一定有过这样的体验:点击一个链接,系统会提示你选择哪一个浏览器打开网页。这些动作都是通过Intent来完成的。接下来我们看看Intent还有什么新玩法。

修改代码如下:

1 @Override
2 public void onClick(View v)
3 {
4     Intent intent = new Intent(Intent.ACTION_VIEW);
5     intent.setData(Uri.parse("http://www.baidu.com"));
6     startActivity(intent);
7 }

我们这里传入的是"ACTION_VIEW"这个action,这是一个系统内置的action。然后我们调用intent的setData方法。这个方法是用来指定我们当前Intent操作的数据,它的参数是一个Uri对象。所以我们里面使用Uri.parse来将一个网址解析成为了一个Uri对象(parse,分析的意思)。然后我们重新运行程序:

 

可以看到我们的程序成功响应了我们的请求,打开了我们指定的网页。

 那我们的程序能不能响应打开网页的请求呢?我们只要在相应的activity标签中去添加属性就可以了。

修改AndroidManifest.xml如下:

1  <activity android:name=".SecondActivity">
2      <intent-filter tools:ignore="AppLinkUrlError">
3          <action android:name="android.intent.action.VIEW" />
4          <category android:name="android.intent.category.DEFAULT" />
5          <data android:scheme="http" />
6      </intent-filter>
7  </activity>

我们修改了SecondActivity的属性,让他能响应所有http协议的网址。并且修改了action为系统内置的action,它能响应Intent.ACTION_VIEW,也就是我们刚才传入的那个值。

我们还能指定的data有:

android:scheme   指定数据的协议,如http;

android:host        指定数据的主机名,如www.baidu.com

android:port         指定端口,比如:8080,:80

还有很多,不常用的就不写在这里了。

我们点击FirstActivity的按钮之后:

可以看到,我们的IntentDemo能够响应网页的请求了,就是因为我们在SecondActivity中添加了一个“可以响应http协议”的属性。

除了网页,我们还可以让其响应拨号事件:

1 Intent intent = new Intent(Intent.ACTION_DIAL);
2 intent.setData(Uri.parse("tel:10010"));

使用Intent传递数据

传递数据给下一个活动

到目前为止,我们还只是使用Inten来跳转活动。但是我们如果有需求,让活动在跳转的时候传递数据呢?

很简单,Intent是一个桥梁,你把你想传的放在桥上,然后让另外一个人过来取不就行了吗。Intent为我们提供了一个各式各样的篮子,我们根据我们的需要,将数据放在篮子里就行了。

上代码!

1  @Override
2  public void onClick(View v)
3  {
4      String data = "马什么梅?";
5      Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
6      intent.putExtra("my_data", data);
7      startActivity(intent);
8  }

我们定义了一个字符串,用来作为传递的数据。(马冬什么?)然后我们使用的是显式Intent,并使用putExtra(String name,DataType value)方法来传值的(DataType代表很多数据类型)。

第一个参数,是这个数据的“键”。你可以理解为关键字,也可以简单的理解这个数据的名字。你把数据放我这个大篮子里面了,不得标示一下这个数据的身份吗,否则到时候用找谁拿去啊。

第二个参数就是我们的数据了。

然后我们在SecondActivity中相应的去接收数据:

1  @Override
2  protected void onCreate(Bundle savedInstanceState)
3  {
4      super.onCreate(savedInstanceState);
5      setContentView(R.layout.activity_second);
6      Intent intent = getIntent();
7      String data = intent.getStringExtra("my_data");
8      Toast.makeText(SecondActivity.this, data, Toast.LENGTH_SHORT).show();
9  }

我们定义了一个Intent,并用getIntent()方法来获取到用来启动这个activity的Intent。然后使用getStringExtra(String name)来获取我们存在“篮子”里面的字符串,参数当然就是我们刚才设置的数据的名字(键)。为了展示是否成功,我就简单的去Toast了一下。

可以看到,我们成功返回了数据。我们这里传的是字符串,要是Boolean就是getExtraBoolean,其他的以此类推,传的什么类型就接什么。

 返回数据给上一个活动

我们传递数据给下一个活动是使用的Intent来暂存的,但是我们要是想直接返回上一个活动只需要按下返回键就可以了,并没有什么Intent参与其中。这时候我们的思路就要转换一下了。你不主动给我?那好,我直接在启动你的时候向你伸手要总行了吧!

修改FirstActivity的代码如下:

1  @Override
2  public void onClick(View v)
3  {
4      Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
5      startActivityForResult(intent,1);
6  }

既然是张嘴要,就给在启动的时候说明白了。使用startActivityForResult(Intent intent,int requestCode),第一个就是我们的Intent,第二个是请求码。要是有很多数据返回来的话,我们要对他们进行区分,这就是请求码的用意。

 接下来就是SecondActivity:

1 @Override
2 public void onClick(View v)
3 {
4     Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
5     intent.putExtra("data_return", "什么冬梅?");
6     setResult(RESULT_OK, intent);7 }

我们还是构建了一个Intent来跳转到上一个活动。然后放一个字符串,并使用setResult(int resultCode,Intent data)来向上一个活动传值。第一个是结果值,一般使用RESULT_OK和RESULT_CANCELED两个值,用来告诉上一个活动返回数据的处理结果。第二个就是我们的intent了。

我们既然要向上一个活动返回数据,就得有相应的措施来处理返回数据。

添加FirstActivity的代码:

 1 @Override
 2 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
 3 {
 4     switch (requestCode)
 5     {
 6         case 1:
 7             if (resultCode == RESULT_OK)
 8                 Toast.makeText(FirstActivity.this, data.getStringExtra("data_return"), Toast.LENGTH_SHORT).show();
 9             break;
10         default:
11     }
12 }

我们重写了FirstActivity的onActivityResult方法。这个方法接收三个参数,具体意义就不讲了,都能看明白。

因为数据会有很多,所以我们第一件事就是去判断数据来源,也就是我们的requestCode。因为如果有多个时间指向同一activity的话我们就必须分清数据从哪里来。然后我们还需要去检查结果码,看看是不是成功了。

好了,这就是Intent的内容,对于我们初学者来说,这些内容很够了。

菜鸟一个,多多指教!

猜你喜欢

转载自www.cnblogs.com/KangYh/p/9936813.html