zoukankan      html  css  js  c++  java
  • android菜鸟学习笔记11----Intent的两点补充

    关于Intent的两点补充

    1.隐式Intent启动组件,会有一个Intent解析的过程,若找不到能够处理该Intent的组件,程序就会异常终止。一个合理的做法是,在使用Intent实例启动组件如:startActivity(intent)之前,最好能判断一下该调用能否解析为一个Activity。为了实现该功能,Intent提供了一个方法:

    ComponentName  resolveActivity(PackageManager pm)  :该方法接收一个包管理器对象作为参数,通过查找该包管理器,返回能够处理该Intent的Activity的Component对象,没有找到能处理该Inent的组件时则返回null。

                     Intent intent1 = new Intent();
    
                     intent1.setAction(Intent.ACTION_VIEW);
    
                     intent1.setType("text/html");
    
                     Log.i("tag",intent1.toString());
    
                     ComponentName resolveActivity = intent1.resolveActivity(getPackageManager());
    
                     Log.i("tag",resolveActivity.getClassName());
    
                     Log.i("tag",resolveActivity.getPackageName());
    
                     Log.i("tag",resolveActivity.toString());
    
                     startActivity(intent1);            

    NormalActivity中配置<intent-filter>

     1 <activity android:name=".NormalActivity">
     2 
     3             <intent-filter >
     4 
     5                 <action android:name="android.intent.action.VIEW"/>
     6 
     7                 <category android:name="android.intent.category.DEFAULT"/>
     8 
     9                 <data android:mimeType="text/html"/>
    10 
    11             </intent-filter>
    12 
    13 </activity>

    运行信息:

     

    可见解析到cn.csc.lifecycle.NormalActivity能够处理该Intent。

    若找不到能够处理该Intent的组件时,会返回null,所以,安全的启动Activity的做法是:

    1 if(intent1.resolveActivity(getPackageManager())!=null){
    2 
    3                       startActivity(intent1);
    4 
    5 }

    当然,可以加上找不到能处理intent1的组件的提示信息等。

    注意,若用多个组件都能处理该Intent实例时,如:

     1 Intent intent1 = new Intent();
     2 
     3 intent1.setAction(Intent.ACTION_VIEW);
     4 
     5 intent1.setData(Uri.parse("http://www.baidu.com"));
     6 
     7 Log.i("tag",intent1.toString());
     8 
     9 ComponentName resolveActivity = intent1.resolveActivity(getPackageManager());
    10 
    11 Log.i("tag",resolveActivity.toString());
    12 
    13 startActivity(intent1);
     1 <activity android:name=".NormalActivity">
     2 
     3             <intent-filter >
     4 
     5                 <action android:name="android.intent.action.VIEW"/>
     6 
     7                 <category android:name="android.intent.category.DEFAULT"/>
     8 
     9                 <data android:scheme="http"/>
    10 
    11             </intent-filter>
    12 
    13 </activity>

    此时,浏览器和NormalActivity都能处理该Intent实例。

    运行效果:

     

    返回的Component信息为:

     

    这个ResolverActivity其实就是一个选择打开程序的对话框,当有多个组件能处理Intent实例,但是没有设置默认的处理程序时,就会交由ResolverActivty来处理,而ResolverActivity的做法就是把所有能处理的都显示在一个列表中,由用户决定采用哪个来处理。当我们勾选了下面的use by default for this action时,之后选择的组件将会作为该Intent的默认处理程序,该设置会保存在手机或者模拟器中,下次在出现该Intent时,直接使用设置的默认组件去处理,而不再转到ResolverActivity。

    如,这里我选择了Browser作为默认处理程序,下次再启动改程序,输出的运行信息:

     

    2.关于使用Intent在Activity之间传递数据,在之前都是传递些内置类型的数据,若想传递自定义类型的数据,应该怎么办呢?

    注意到在Intent中有下面两对方法:

    Serializable  getSerializableExtra(String name) 

    Intent  putExtra(String name, Serializable value)

    放入/获取Serializable类型的值。 

    <T extends Parcelable> T  getParcelableExtra(String name) 

    Intent  putExtra(String name, Parcelable value) 

    放入/获取Parcelable类型的值。

    Serializable和Parcelable都是接口,即要想使用Intent传递自定义类型的数据,则自定义类型的数据应当事先Serializable接口或者Parcelable接口。

    Serializable接口

    java.io.Serializable是一个空的起到标记作用的接口。标记实现该接口,只需要在类定义时声明实现该接口即可。实现该接口的类表明能够被序列化和反序列化,对大多数的类来说已然足够了,当然,若想更细粒度的操纵序列化过程,可以实现下面这两个方法:

    private void writeObject(java.io.ObjectOutputStream out) throws IOException

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException

    一般情况下,都用不到的。

    这里简单声明实现该接口,如:

     1 import java.io.Serializable;
     2 
     3  
     4 
     5 public class MyData implements Serializable {
     6 
     7       private String stringData;
     8 
     9       private int intData;
    10 
    11 public MyData(String stringData, int intData) {
    12 
    13            super();
    14 
    15            this.stringData = stringData;
    16 
    17            this.intData = intData;
    18 
    19       }
    20 
    21       public String getStringData() {
    22 
    23            return stringData;
    24 
    25       }
    26 
    27       public void setStringData(String stringData) {
    28 
    29            this.stringData = stringData;
    30 
    31       }
    32 
    33       public int getIntData() {
    34 
    35            return intData;
    36 
    37       }
    38 
    39       public void setIntData(int intData) {
    40 
    41            this.intData = intData;
    42 
    43       }
    44 
    45 }

    之后,便可以传递MyData类型数据了:

    1 MyData  data1 = new MyData(“aaa”,111);
    2 
    3 Intent intent1 = new Intent();
    4 
    5 intent1.putExtra(“mydata”, data1);

    取得该数据:

    1 MyData  data1 = (MyData)getIntent.getSerializableExtra(“data1”);

    Parcelable接口:相比Serializable要复杂一点,需要实现里面的抽象方法。

    android.os.Parcelable接口,帮助文档中,有一个典型的实现例子如下,可以用作参考,自己实现该接口时,模仿即可:

     1 public class MyParcelable implements Parcelable {    
     2 
     3       private int mData;    
     4 
     5       public int describeContents() {        
     6 
     7            return 0;    
     8 
     9            }    
    10 
    11       public void writeToParcel(Parcel out, int flags) {
    12 
    13            out.writeInt(mData);    
    14 
    15            }    
    16 
    17       public static final Parcelable.Creator<MyParcelable> CREATOR            
    18 
    19       = new Parcelable.Creator<MyParcelable>() {        
    20 
    21            public MyParcelable createFromParcel(Parcel in) {
    22 
    23                  return new MyParcelable(in);         
    24 
    25                  }        
    26 
    27            public MyParcelable[] newArray(int size) {            
    28 
    29                  return new MyParcelable[size];        
    30 
    31                  }    
    32 
    33            };         
    34 
    35       private MyParcelable(Parcel in) {      
    36 
    37            mData = in.readInt();    
    38 
    39       }
    40 
    41 }

    定义各种内置类型的数据,然后在writeToParcel分别根据不同的类型调用对应类型的

    out.writeXXX(mData);在构造方法中,分别调用in.readXX()即可。

    然后就可以调用Intent  putExtra(String name, Parcelable value)去放入该自定义类型数据,调用<T extends Parcelable> T  getParcelableExtra(String name)获取该自定义类型数据。

  • 相关阅读:
    Oracle数据库链Database links
    记录中文字符的烦恼
    oracle游标应用难点 sys_refcursor 和 cursor(转)
    C# Delegate类
    Oracle_merge into 中 using 后的查询表如果有参数的情况
    C# partial
    Excel快捷键
    时间格式的问题
    Ref_cursor
    .Net 引用命名空间
  • 原文地址:https://www.cnblogs.com/dqrcsc/p/4611519.html
Copyright © 2011-2022 走看看