zoukankan      html  css  js  c++  java
  • 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的内容,对于我们初学者来说,这些内容很够了。

    菜鸟一个,多多指教!

  • 相关阅读:
    MVC ActionResult JsonResult
    xml文件
    使用socket实现聊天功能
    使用多线程完成Socket
    Socket编程
    U1总结
    多线程
    IO
    单例模式
    日期
  • 原文地址:https://www.cnblogs.com/KangYh/p/9936813.html
Copyright © 2011-2022 走看看