精华内容
下载资源
问答
  • 使用Intent传递数据 在通过intent来启动Activity,Service,发送广播时候,可以传递一些附加数据。 一. 使用Intent传递常规数据(基本数据类型, 字符串) 在第一个activity中使用 intent.putExtra("数据id", 需要传递的...

    Android-使用Intent传递数据

    在通过intent来启动Activity,Service,发送广播时候,可以传递一些附加数据。

    一. 使用Intent传递常规数据(基本数据类型, 字符串)

    在第一个activity中使用

    intent.putExtra("数据id", 需要传递的数据)
    

    进行数据传递

    比如

       val intent = Intent(this, SecondActivity::class.java)
                    //传递整数
                    intent.putExtra("extra_int", 1)
                    //传递字符串
                    intent.putExtra("extra_string", "需要传递的字符串")
                    startActivity(intent)
    

    在第二个activity中使用intent.get类型Extra来获取数据,比如:

     		//获取传递的int类型值
            val extraInt = intent.getIntExtra("extra_int", -1)
            //获取传递的字符串值
            val extraString = intent.getStringExtra("extra_string")
    

    二. 使用Intent传递自定义对象

    上面说的常规数据可以满足大部分情况下的数据传递,但是有时候需要传递一些自定义的数据类型,比如下面的Fruit类

    class Fruit(var mName: String, var mWeight: Int){
    }
    

    这时候就需要将这个数据类型进行序列化,然后才能通过Intentc传递,序列化的方式有两种,分别是实现Serializable接口和实现Parcelable接口,两种方式的优缺点也都很明显:

    Seriaizable:实现方式简单,但是会把整个对象序列化,导致效率比较低

    Parcelable:实现方式略复杂,但效率更高

    通常情况下更推荐使用Parcelable来实现通过Intent传递对象的方式

    1.Serializable方式

    即直接继承Serializable接口

    class Fruit(var mName: String, var mWeight: Int) : Serializable {
    }
    

    传递方式与基本数据类型的传递类似,在第一个activity中:

     val fruit = Fruit("apple", 350)
                    intent.putExtra("extra_fruit", fruit)
                    startActivity(intent)
    

    在第二个activity中

      val extraFruit = intent.getSerializableExtra("extra_fruit") as Fruit
            val extraFruitName = extraFruit.mName
            val extraFruitWeight = extraFruit.mWeight
    

    2.Parcelable方式

    与Serializable不同,Parcelable是将对象,对分解后的每一部分进行传递,从而实现传递对象的功能、

    继承Parcelable接口,重写writeToParcel方法,将成员变量写入:

    override fun writeToParcel(dest: Parcel, flags: Int) {
            dest?.apply {
                writeString(mName)
                writeInt(mWeight)
            }
        }
    

    重写describeContents方法,一般返回0即可,含有文件描述符(ParcelFileDescriptor)时返回CONTENTS_FILE_DESCRIPTOR

      override fun describeContents(): Int {
            return 0
        }
    

    创建CREATEOR对象,createFromParcel中创建对象,并为对象的成员变量赋值

    companion object CREATOR : Parcelable.Creator<Fruit> {
            override fun createFromParcel(parcel: Parcel): Fruit {
                return Fruit(parcel.readString(), parcel.readInt())
            }
    
            override fun newArray(size: Int): Array<Fruit?> {
                return arrayOfNulls(size)
            }
        }
    

    完整代码:

    class Fruit(var mName: String?, var mWeight: Int) : Parcelable {
    
        override fun writeToParcel(dest: Parcel, flags: Int) {
            dest?.apply {
                writeString(mName)
                writeInt(mWeight)
            }
        }
    
        override fun describeContents(): Int {
            return 0
        }
    
        companion object CREATOR : Parcelable.Creator<Fruit> {
            override fun createFromParcel(parcel: Parcel): Fruit {
                return Fruit(parcel.readString(), parcel.readInt())
            }
    
            override fun newArray(size: Int): Array<Fruit?> {
                return arrayOfNulls(size)
            }
        }
    }
    

    Kotlin中还提供了一种使用注解的快捷写法,作用与上面的写法相同:

    @Parcelize
    class Fruit(var mName: String?, var mWeight: Int) : Parcelable {
    }
    

    传递方式与之前类似,在第一个activity中:

    val fruit = Fruit("apple", 350)
                    intent.putExtra("extra_fruit", fruit)
                    startActivity(intent)
    

    在第二个activity中:

      val extraFruit = intent.getParcelableExtra<Fruit>("extra_fruit")
            val extraFruitName = extraFruit?.mName
            val extraFruitWeight = extraFruit?.mWeight
    
    展开全文
  • Intent传递数据全解

    2020-12-20 12:53:40
    Intent传递简单数据能够以直接通过调用Intent的putExtra()方法存入数据,然后在获得Intent后调用getXxxExtra获得 相应类型的数据。传递多个的话。能够使用Bundle对象作为容器,通过调用Bundle的putXxx先将数据 存储...

    概述

    之前的博文也有介绍,查看—->用户界面开发基础

    这里单独抽取出来,更加具体的记录一下,事实上主要是API的使用。

    Intent传递简单数据

    能够以直接通过调用Intent的putExtra()方法存入数据,然后在获得Intent后调用getXxxExtra获得 相应类型的数据。传递多个的话。能够使用Bundle对象作为容器,通过调用Bundle的putXxx先将数据 存储到Bundle中,然后调用Intent的putExtras()方法将Bundle存入Intent中,然后获得Intent以后, 调用getExtras()获得Bundle容器,然后调用其getXXX获取相应的数据。

    Intent传递数组

    写入数组:

    bd.putStringArray("StringArray", new String[]{"xx","oo"});

    //可把StringArray换成其它数据类型,比方int,float等等,具体查看API

    读取数组:

    String[] str = bd.getStringArray("StringArray")

    Intent传递集合

    List

    写入集合:

    intent.putStringArrayListExtra(name, value)

    intent.putIntegerArrayListExtra(name, value)

    读取集合:

    intent.getStringArrayListExtra(name)

    intent.getIntegerArrayListExtra(name)

    List< Object>

    将list强转成Serializable类型,然后传入(可用Bundle做媒介)

    写入集合:

    putExtras(key, (Serializable)list)

    读取集合:

    (List) getIntent().getSerializable(key)

    PS:Object类须要实现Serializable接口

    Map

    //传递复杂些的參数

    Map map1 = new HashMap();

    map1.put("key1", "value1");

    map1.put("key2", "value2");

    List> list = new ArrayList>();

    list.add(map1);

    Intent intent = new Intent();

    intent.setClass(MainActivity.this,ComplexActivity.class);

    Bundle bundle = new Bundle();

    //须定义一个list用于在budnle中传递须要传递的ArrayList,这个是必须要的

    ArrayList bundlelist = new ArrayList();

    bundlelist.add(list);

    bundle.putParcelableArrayList("list",bundlelist);

    intent.putExtras(bundle);

    startActivity(intent);

    Intent传递对象

    传递对象的方式有两种:将对象转换为Json字符串或者通过Serializable,Parcelable序列化 不建议使用Android内置的抠脚Json解析器,可使用fastjson或者Gson第三方库!

    将对象转换为Json字符串

    Gson解析的样例:

    Model:

    public class Author{

    private int id;

    private String name;

    // ....

    }

    写入数据:

    Book book=new Book();

    book.setTitle("Java编程思想");

    Author author=new Author();

    author.setId(1);

    author.setName("Bruce Eckel");

    book.setAuthor(author);

    Intent intent=new Intent(this,SecondActivity.class);

    intent.putExtra("book",new Gson().toJson(book));

    startActivity(intent);

    读取数据:

    String bookJson=getIntent().getStringExtra("book");

    Book book=new Gson().fromJson(bookJson,Book.class);

    Log.d(TAG,"book title->"+book.getTitle());

    Log.d(TAG,"book author name->"+book.getAuthor().getName());

    使用Serializable,Parcelable序列化对象

    Serializable实现:

    ①业务Bean实现:Serializable接口,写上getter和setter方法

    ②Intent通过调用putExtra(String name, Serializable value)传入对象实例 当然对象有多个的话多个的话,我们也能够先Bundle.putSerializable(x,x);

    ③新Activity调用getSerializableExtra()方法获得对象实例: eg:Product pd = (Product) getIntent().getSerializableExtra(“Product”);

    ④调用对象get方法获得相应參数

    Parcelable实现:

    一般流程:

    ①业务Bean继承Parcelable接口,重写writeToParcel方法,将你的对象序列化为一个Parcel对象;

    ②重写describeContents方法,内容接口描写叙述,默认返回0就能够

    ③实例化静态内部对象CREATOR实现接口Parcelable.Creator

    ④相同式通过Intent的putExtra()方法传入对象实例,当然多个对象的话,我们能够先 放到Bundle里Bundle.putParcelable(x,x),再Intent.putExtras()就可以。

    通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射 成你的对象。也能够将Parcel看成是一个流,通过writeToParcel把对象写到流里面, 在通过createFromParcel从流里读取对象,仅仅只是这个过程须要你来实现。因此写的 顺序和读的顺序必须一致。

    实现Parcelable接口的代码演示样例:

    //Internal Description Interface,You do not need to manage

    @Override

    public int describeContents() {

    return 0;

    }

    @Override

    public void writeToParcel(Parcel parcel, int flags){

    parcel.writeString(bookName);

    parcel.writeString(author);

    parcel.writeInt(publishTime);

    }

    public static final Parcelable.Creator CREATOR = new Creator() {

    @Override

    public Book[] newArray(int size) {

    return new Book[size];

    }

    @Override

    public Book createFromParcel(Parcel source) {

    Book mBook = new Book();

    mBook.bookName = source.readString();

    mBook.author = source.readString();

    mBook.publishTime = source.readInt();

    return mBook;

    }

    };

    Android Studio生成Parcleable插件:

    Intellij/Andriod Studio插件android-parcelable-intellij-plugin 仅仅要ALT+Insert,就可以直接生成Parcleable接口代码。

    另外:Android中大量用到Parcelable对象,实现Parcable接口又是非常繁琐的,能够用到 第三方的开源框架:Parceler

    两种序列化方式的比較

    1)在使用内存的时候。Parcelable比Serializable性能高,所以推荐使用Parcelable。

    2)Serializable在序列化的时候会产生大量的暂时变量。从而引起频繁的GC。

    3)Parcelable不能使用在要将数据存储在磁盘上的情况,由于Parcelable不能非常好的保证数据的 持续性在外界有变化的情况下。虽然Serializable效率低点,但此时还是建议使用Serializable。

    Intent传递Bitmap

    bitmap默认实现Parcelable接口,直接传递就可以

    Bitmap bitmap = XXXX;

    Intent intent = new Intent();

    Bundle bundle = new Bundle();

    bundle.putParcelable("bitmap", bitmap);

    intent.putExtra("bundle", bundle);

    通过全局对象传递数据

    假设你想某个数据能够在不论什么地方都能获取到,你就能够考虑使用 Application全局对象了!

    Android系统在每一个程序执行的时候创建一个Application对象。并且仅仅会创建一个,所以Application 是单例(singleton)模式的一个类。并且Application对象的生命周期是整个程序中最长的,他的生命 周期等于这个程序的生命周期。

    假设想存储一些比静态的值(固定不改变的。也能够变),假设你想使用 Application就须要自己定义类实现Application类,并且告诉系统实例化的是我们自己定义的Application 而非系统默认的。而这一步,就是在AndroidManifest.xml中加入application标签加入:name属性。

    注意事项

    Application对象是存在于内存中的,也就有它可能会被系统杀死。比方这种场景:

    我们在Activity1中往application中存储了用户账号,然后在Activity2中获取到用户账号,并且显示。

    假设我们点击home键。然后过了N久候,系统为了回收内存kill掉了我们的app。这个时候。我们又一次 打开这个app,这个时候非常奇妙的,回到了Activity2的页面。可是假设这个时候你再去获取Application 里的用户账号,程序就会报NullPointerException。然后crash掉~

    之所以会发生上述crash,是由于这个Application对象是全新创建的,可能你以为App是又一次启动的。 事实上并非。仅仅是创建一个新的Application,然后启动上次用户离开时的Activity,从而创造App 并没有被杀死的假象!所以假设是比較重要的数据的话,建议你还是进行本地化。另外在使用数据的时候 要对变量的值进行非空检查!

    另一点就是:不止是Application变量会这样。单例对象以及公共静态变量 也会这样~

    单例模式的MyApplication

    依照上述的写法,获取context ,须要这样。

    // 获取全局变量

    AppContext context = (AppContext)getApplication();

    String name = context.appName;

    Data data = context.data;

    假设认为麻烦,能够写成单例模式。比方

    private String myState;

    private static MyApp instance;

    public static MyApp getInstance(){

    return instance;

    }

    public String getState(){

    return myState;

    }

    public void setState(String s){

    myState = s;

    }

    @Override

    public void onCreate(){

    onCreate();

    instance = this;

    }

    }

    然后在随意地方我们就能够直接调用:MyApp.getInstance()来获得Application的全局对象!

    单例模式传參

    上面的Application就是基于单例的。单例模式的特点就是能够保证系统中一个类有且仅仅有一个实例。

    这样非常easy就能实现。在A中设置參数,在B中直接訪问了。这是几种方法中效率最高的。

    单例类

    public class XclSingleton

    {

    //单例模式实例

    private static XclSingleton instance = null;

    //synchronized 用于线程安全,防止多线程同一时候创建实例

    public synchronized static XclSingleton getInstance(){

    if(instance == null){

    instance = new XclSingleton();

    }

    return instance;

    }

    final HashMap mMap;

    private XclSingleton()

    {

    mMap = new HashMap();

    }

    public void put(String key,Object value){

    mMap.put(key,value);

    }

    public Object get(String key)

    {

    return mMap.get(key);

    }

    }

    设置參数

    XclSingleton.getInstance().put("key1", "value1");

    XclSingleton.getInstance().put("key2", "value2");

    展开全文
  • Intent数据传输

    2021-06-05 15:30:44
    Activity间的数据通信,对于数据量比较大的,避免使用intent+Parcelable的方式,可以考虑EventBus等代替方法,以免造成TransactionTooLargeException;

    在学习时,看到公司的规范里有句话:

    Activity间的数据通信,对于数据量比较大的,避免使用intent+Parcelable的方式,可以考虑EventBus等代替方法,以免造成TransactionTooLargeException;

    因为刚开始,不太了解内部的原理,如果只是死记硬背肯定是不行的,因此想对该问题做一个深入的分析:

    1、首先需要理解intent时如何传递数据的。

    通常,我们在Activity中传递数据,都是将数据方法Intent中,然后调用startActivity或startActivityForResult来拉起另一个Activity的。

    Intent mSecondIntent = new Intent(MainActivity.this, SecondActivity.class);
    byte[] val = new byte[1024*10];
    mSecondIntent.putExtra("byteArr", val);
    startActivity(mSecondIntent);

    这里的putExtra()有多个重载,可以实现不同数据的传递,通过源码我们可以看到:

    public @NonNull Intent putExtra(String name, @Nullable byte[] value) {
           if (mExtras == null) {
               mExtras = new Bundle();
           }
           mExtras.putByteArray(name, value);
           return this;
       }

    实际上是通过一个内部变量mExtras,将其存储在Bundle中的。
    所以传递数据就算通过Intent来实现的。

    2、通过Intent+Parcelable数据:

    Parcelable是Android为我们提供的序列化(将对象转换为可以传输的二进制流/序列)接口:public interface Parcelable{}//它是一个接口,并且通过Android源码注释,我们需要定义自己的Parcelable类来实现它。实际上就是通过Parcel写入和回复数据。需要实现describeContent()、writeToParcel(),以及反序列化----定义一个变量CREATOR,通过匿名内部类实现Parcelable中的Creator接口。

    Android的Pracelable的注释中有一个简单的使用例子:

    /**
     * Interface for classes whose instances can be written to
     * and restored from a {@link Parcel}.  Classes implementing the Parcelable
     * interface must also have a non-null static field called <code>CREATOR</code>
     * of a type that implements the {@link Parcelable.Creator} interface.
     * 
     * <p>A typical implementation of Parcelable is:</p>
     * 
     * <pre>
     * public class MyParcelable implements Parcelable {
     *     private int mData;
     *
     *     public int describeContents() {
     *         return 0;
     *     }
     *
     *     public void writeToParcel(Parcel out, int flags) {
     *         out.writeInt(mData);
     *     }
     *
     *     public static final Parcelable.Creator&lt;MyParcelable&gt; CREATOR
     *             = new Parcelable.Creator&lt;MyParcelable&gt;() {
     *         public MyParcelable createFromParcel(Parcel in) {
     *             return new MyParcelable(in);
     *         }
     *
     *         public MyParcelable[] newArray(int size) {
     *             return new MyParcelable[size];
     *         }
     *     };
     *     
     *     private MyParcelable(Parcel in) {
     *         mData = in.readInt();
     *     }
     * }</pre>
     */
    public interface Parcelable {


    所以,Parcelable就算用来传递对象或对象数组的时候用到的东西,实际上最后传递数据时,还是和前面说到的一样,通过Intent.putExtrac()将其放到Intent中,然后调用startActivity()将其传递出去;

    3、为何大数据不能用Intent+Parcelable

    实际上就算不能用Intent,因为不管是否Parcelable对象,只要数据足够大的时候,都不能用Intent,我们使用byte模拟下传递1M数据的场景:(为什么1M后面会说)

    Intent mSecondIntent = new Intent(MainActivity.this, SecondActivity.class);
    byte[] val = new byte[1024*1024];
    
    mSecondIntent.putExtra("byteArr", val);
    startActivity(mSecondIntent);

    会报如下错误:

    2021-06-05 14:32:39.264 20256-20256/com.example.myapplication E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 1049016 2021-06-05 14:32:39.264 20256-20256/com.example.myapplication D/AndroidRuntime: Shutting down VM 2021-06-05 14:32:39.267 20256-20256/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.myapplication, PID: 20256 java.lang.RuntimeException: Failure from system at android.app.Instrumentation.execStartActivity(Instrumentation.java:1711) at android.app.Activity.startActivityForResult(Activity.java:5192) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676) at android.app.Activity.startActivityForResult(Activity.java:5150) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663) at android.app.Activity.startActivity(Activity.java:5521) at android.app.Activity.startActivity(Activity.java:5489) at com.example.myapplication.MainActivity.lambda$onCreate$0$MainActivity(MainActivity.java:38) at com.example.myapplication.-$$Lambda$MainActivity$jRtpOGtrw8cqMNyhtDGNK0XOTPE.onClick(Unknown Source:2) at android.view.View.performClick(View.java:7125) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992) at android.view.View.performClickInternal(View.java:7102) at android.view.View.access$3500(View.java:801) at android.view.View$PerformClick.run(View.java:27336) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) Caused by: android.os.TransactionTooLargeException: data parcel size 1049016 bytes at android.os.BinderProxy.transactNative(Native Method) at android.os.BinderProxy.transact(BinderProxy.java:510) at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:3847) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1705) at android.app.Activity.startActivityForResult(Activity.java:5192) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676) at android.app.Activity.startActivityForResult(Activity.java:5150) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663) at android.app.Activity.startActivity(Activity.java:5521) at android.app.Activity.startActivity(Activity.java:5489) at com.example.myapplication.MainActivity.lambda$onCreate$0$MainActivity(MainActivity.java:38) at com.example.myapplication.-$$Lambda$MainActivity$jRtpOGtrw8cqMNyhtDGNK0XOTPE.onClick(Unknown Source:2) at android.view.View.performClick(View.java:7125) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992) at android.view.View.performClickInternal(View.java:7102) at android.view.View.access$3500(View.java:801) at android.view.View$PerformClick.run(View.java:27336) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

    2021-06-05 14:32:39.275 20256-20256/com.example.myapplication I/Process: Sending signal. PID: 20256 SIG: 9
    可以看到这是一个 Caused by: android.os.TransactionTooLargeException: 异常,我们先看TransactionToolLargeException这个异常定义,在frameworks/base/core/java/android/os/TransactionTooLargeException.java文件中:

    The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process.

    文件中注释可以看到,我们现在限制Binder transaction的内存大小就为1M。
    所以这个应该是因为传递过程中,数据量超过了Binder所能传递的最大内存,报TooLarge异常。

    4、startActivity()如何传递数据的:

    根据堆栈信息和源码,我们调用startActivity()后,会调到Activity.startActivity()。最后在Instrumentation.java#execStartActivity()中调用ActivityTaskManager.getService().startActivity();
    在这个过程中,Intent都是作为参数传递进去的,过程中可能还会往里面添加一些数据。
    在ActivityTaskManager.getService()会得到一个IActivityTaskManager.Stub.Prox的Binder代理对象(这个和Binder通信有关,在android/app/目录下存在IActivityTaskManager.aidl文件,这个Java端的Prox就算通过aidl自动生成的)
    我们可以模拟该情况,自己写一个aidl文件,其中Intent参数作为in:

    // IActivityTaskManager.aidl
    package com.example.myapplication;
    
    import android.content.Intent;
    
    /**
     * System private API for talking with the activity task manager that handles how activities are
     * managed on screen.
     *
     * {@hide}
     */
    interface IActivityTaskManager {
        //int startActivity(int a);
        int startActivity(in Intent intent);
    }

    使用AS自动生成java文件中的startActivity()如下所示:

    package com.example.myapplication;
    /**
     * System private API for talking with the activity task manager that handles how activities are
     * managed on screen.
     *
     * {@hide}
     */
    public interface IActivityTaskManager extends android.os.IInterface
    {
      /** Default implementation for IActivityTaskManager. */
      public static class Default implements com.example.myapplication.IActivityTaskManager
      {
        //int startActivity(int a);
    
        @Override public int startActivity(android.content.Intent intent) throws android.os.RemoteException
        {
          return 0;
        }
        @Override
        public android.os.IBinder asBinder() {
          return null;
        }
      }
      /** Local-side IPC implementation stub class. */
      public static abstract class Stub extends android.os.Binder implements com.example.myapplication.IActivityTaskManager
      {
        private static final java.lang.String DESCRIPTOR = "com.example.myapplication.IActivityTaskManager";
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
          this.attachInterface(this, DESCRIPTOR);
        }
        /**
         * Cast an IBinder object into an com.example.myapplication.IActivityTaskManager interface,
         * generating a proxy if needed.
         */
        public static com.example.myapplication.IActivityTaskManager asInterface(android.os.IBinder obj)
        {
          if ((obj==null)) {
            return null;
          }
          android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
          if (((iin!=null)&&(iin instanceof com.example.myapplication.IActivityTaskManager))) {
            return ((com.example.myapplication.IActivityTaskManager)iin);
          }
          return new com.example.myapplication.IActivityTaskManager.Stub.Proxy(obj);
        }
        @Override public android.os.IBinder asBinder()
        {
          return this;
        }
        @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
        {
          java.lang.String descriptor = DESCRIPTOR;
          switch (code)
          {
            case INTERFACE_TRANSACTION:
            {
              reply.writeString(descriptor);
              return true;
            }
            case TRANSACTION_startActivity:
            {
              data.enforceInterface(descriptor);
              android.content.Intent _arg0;
              if ((0!=data.readInt())) {
                _arg0 = android.content.Intent.CREATOR.createFromParcel(data);
              }
              else {
                _arg0 = null;
              }
              int _result = this.startActivity(_arg0);
              reply.writeNoException();
              reply.writeInt(_result);
              return true;
            }
            default:
            {
              return super.onTransact(code, data, reply, flags);
            }
          }
        }
        private static class Proxy implements com.example.myapplication.IActivityTaskManager
        {
          private android.os.IBinder mRemote;
          Proxy(android.os.IBinder remote)
          {
            mRemote = remote;
          }
          @Override public android.os.IBinder asBinder()
          {
            return mRemote;
          }
          public java.lang.String getInterfaceDescriptor()
          {
            return DESCRIPTOR;
          }
          //int startActivity(int a);
    
          @Override public int startActivity(android.content.Intent intent) throws android.os.RemoteException
          {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            int _result;
            try {
              _data.writeInterfaceToken(DESCRIPTOR);
              if ((intent!=null)) {
                _data.writeInt(1);
                intent.writeToParcel(_data, 0);
              }
              else {
                _data.writeInt(0);
              }
              boolean _status = mRemote.transact(Stub.TRANSACTION_startActivity, _data, _reply, 0);
              if (!_status && getDefaultImpl() != null) {
                return getDefaultImpl().startActivity(intent);
              }
              _reply.readException();
              _result = _reply.readInt();
            }
            finally {
              _reply.recycle();
              _data.recycle();
            }
            return _result;
          }
          public static com.example.myapplication.IActivityTaskManager sDefaultImpl;
        }
        static final int TRANSACTION_startActivity = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        public static boolean setDefaultImpl(com.example.myapplication.IActivityTaskManager impl) {
          // Only one user of this interface can use this function
          // at a time. This is a heuristic to detect if two different
          // users in the same process use this function.
          if (Stub.Proxy.sDefaultImpl != null) {
            throw new IllegalStateException("setDefaultImpl() called twice");
          }
          if (impl != null) {
            Stub.Proxy.sDefaultImpl = impl;
            return true;
          }
          return false;
        }
        public static com.example.myapplication.IActivityTaskManager getDefaultImpl() {
          return Stub.Proxy.sDefaultImpl;
        }
      }
      //int startActivity(int a);
    
      public int startActivity(android.content.Intent intent) throws android.os.RemoteException;
    }
    

    在这个里面,如果参数存在Intent对象,它会调用intent.writeToParcle()将Intent中的数据写到Parcel类型变量data中。最后通过mRemote.transact()发送给服务端(Binder通信),也就是ActivityTaskManagerService
    该文件在frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

    它是继承自IActivityTaskManager.Stub,也就是通过aidl自动生成的。
    在Prox中通过transact()发送的数据,会调走到Stub的onTransact()中,因此实现了进程间的通信。

    5、总结

    所以,综上,当我们通过Intent来拉起另一个Activity时,会进行进程间通信,通过Binder把Intent中的数据传递出去给ATMS,而这个过程中Binder的内存大小时有限的,当我们传递数据过大时,会触发TransactionTooLargeException异常。

    TODO:EventBus后面学习了之后再做记录

    展开全文
  • intent传递数据总结

    2020-12-20 12:53:44
    常用系统Intent合集大家贴下常用的系统Intent的合集吧,上面没有的欢迎提出~//===============================================================//1.拨打电话// 给移动客服10086拨打电话Uri uri = Uri.parse("tel:...

    常用系统Intent合集

    大家贴下常用的系统Intent的合集吧,上面没有的欢迎提出~

    //===============================================================

    //1.拨打电话

    // 给移动客服10086拨打电话

    Uri uri = Uri.parse("tel:10086");

    Intent intent = new Intent(Intent.ACTION_DIAL, uri);

    startActivity(intent);

    //===============================================================

    //2.发送短信

    // 给10086发送内容为“Hello”的短信

    Uri uri = Uri.parse("smsto:10086");

    Intent intent = new Intent(Intent.ACTION_SENDTO, uri);

    intent.putExtra("sms_body", "Hello");

    startActivity(intent);

    //3.发送彩信(相当于发送带附件的短信)

    Intent intent = new Intent(Intent.ACTION_SEND);

    intent.putExtra("sms_body", "Hello");

    Uri uri = Uri.parse("content://media/external/images/media/23");

    intent.putExtra(Intent.EXTRA_STREAM, uri);

    intent.setType("image/png");

    startActivity(intent);

    //===============================================================

    //4.打开浏览器:

    // 打开百度主页

    Uri uri = Uri.parse("http://www.baidu.com");

    Intent intent = new Intent(Intent.ACTION_VIEW, uri);

    startActivity(intent);

    //===============================================================

    //5.发送电子邮件:(阉割了Google服务的没戏!!!!)

    // 给someone@domain.com发邮件

    Uri uri = Uri.parse("mailto:someone@domain.com");

    Intent intent = new Intent(Intent.ACTION_SENDTO, uri);

    startActivity(intent);

    // 给someone@domain.com发邮件发送内容为“Hello”的邮件

    Intent intent = new Intent(Intent.ACTION_SEND);

    intent.putExtra(Intent.EXTRA_EMAIL, "someone@domain.com");

    intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");

    intent.putExtra(Intent.EXTRA_TEXT, "Hello");

    intent.setType("text/plain");

    startActivity(intent);

    // 给多人发邮件

    Intent intent=new Intent(Intent.ACTION_SEND);

    String[] tos = {"1@abc.com", "2@abc.com"}; // 收件人

    String[] ccs = {"3@abc.com", "4@abc.com"}; // 抄送

    String[] bccs = {"5@abc.com", "6@abc.com"}; // 密送

    intent.putExtra(Intent.EXTRA_EMAIL, tos);

    intent.putExtra(Intent.EXTRA_CC, ccs);

    intent.putExtra(Intent.EXTRA_BCC, bccs);

    intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");

    intent.putExtra(Intent.EXTRA_TEXT, "Hello");

    intent.setType("message/rfc822");

    startActivity(intent);

    //===============================================================

    //6.显示地图:

    // 打开Google地图中国北京位置(北纬39.9,东经116.3)

    Uri uri = Uri.parse("geo:39.9,116.3");

    Intent intent = new Intent(Intent.ACTION_VIEW, uri);

    startActivity(intent);

    //===============================================================

    //7.路径规划

    // 路径规划:从北京某地(北纬39.9,东经116.3)到上海某地(北纬31.2,东经121.4)

    Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4");

    Intent intent = new Intent(Intent.ACTION_VIEW, uri);

    startActivity(intent);

    //===============================================================

    //8.多媒体播放:

    Intent intent = new Intent(Intent.ACTION_VIEW);

    Uri uri = Uri.parse("file:///sdcard/foo.mp3");

    intent.setDataAndType(uri, "audio/mp3");

    startActivity(intent);

    //获取SD卡下所有音频文件,然后播放第一首=-=

    Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");

    Intent intent = new Intent(Intent.ACTION_VIEW, uri);

    startActivity(intent);

    //===============================================================

    //9.打开摄像头拍照:

    // 打开拍照程序

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    startActivityForResult(intent, 0);

    // 取出照片数据

    Bundle extras = intent.getExtras();

    Bitmap bitmap = (Bitmap) extras.get("data");

    //另一种:

    //调用系统相机应用程序,并存储拍下来的照片

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    time = Calendar.getInstance().getTimeInMillis();

    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment

    .getExternalStorageDirectory().getAbsolutePath()+"/tucue", time + ".jpg")));

    startActivityForResult(intent, ACTIVITY_GET_CAMERA_IMAGE);

    //===============================================================

    //10.获取并剪切图片

    // 获取并剪切图片

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);

    intent.setType("image/*");

    intent.putExtra("crop", "true"); // 开启剪切

    intent.putExtra("aspectX", 1); // 剪切的宽高比为1:2

    intent.putExtra("aspectY", 2);

    intent.putExtra("outputX", 20); // 保存图片的宽和高

    intent.putExtra("outputY", 40);

    intent.putExtra("output", Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路径

    intent.putExtra("outputFormat", "JPEG");// 返回格式

    startActivityForResult(intent, 0);

    // 剪切特定图片

    Intent intent = new Intent("com.android.camera.action.CROP");

    intent.setClassName("com.android.camera", "com.android.camera.CropImage");

    intent.setData(Uri.fromFile(new File("/mnt/sdcard/temp")));

    intent.putExtra("outputX", 1); // 剪切的宽高比为1:2

    intent.putExtra("outputY", 2);

    intent.putExtra("aspectX", 20); // 保存图片的宽和高

    intent.putExtra("aspectY", 40);

    intent.putExtra("scale", true);

    intent.putExtra("noFaceDetection", true);

    intent.putExtra("output", Uri.parse("file:///mnt/sdcard/temp"));

    startActivityForResult(intent, 0);

    //===============================================================

    //11.打开Google Market

    // 打开Google Market直接进入该程序的详细页面

    Uri uri = Uri.parse("market://details?id=" + "com.demo.app");

    Intent intent = new Intent(Intent.ACTION_VIEW, uri);

    startActivity(intent);

    //===============================================================

    //12.进入手机设置界面:

    // 进入无线网络设置界面(其它可以举一反三)

    Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);

    startActivityForResult(intent, 0);

    //===============================================================

    //13.安装apk:

    Uri installUri = Uri.fromParts("package", "xxx", null);

    returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

    //===============================================================

    //14.卸载apk:

    Uri uri = Uri.fromParts("package", strPackageName, null);

    Intent it = new Intent(Intent.ACTION_DELETE, uri);

    startActivity(it);

    //===============================================================

    //15.发送附件:

    Intent it = new Intent(Intent.ACTION_SEND);

    it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");

    it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3");

    sendIntent.setType("audio/mp3");

    startActivity(Intent.createChooser(it, "Choose Email Client"));

    //===============================================================

    //16.进入联系人页面:

    Intent intent = new Intent();

    intent.setAction(Intent.ACTION_VIEW);

    intent.setData(People.CONTENT_URI);

    startActivity(intent);

    //===============================================================

    //17.查看指定联系人:

    Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, info.id);//info.id联系人ID

    Intent intent = new Intent();

    intent.setAction(Intent.ACTION_VIEW);

    intent.setData(personUri);

    startActivity(intent);

    //===============================================================

    //18.调用系统编辑添加联系人(高版本SDK有效):

    Intent it = newIntent(Intent.ACTION_INSERT_OR_EDIT);

    it.setType("vnd.android.cursor.item/contact");

    //it.setType(Contacts.CONTENT_ITEM_TYPE);

    it.putExtra("name","myName");

    it.putExtra(android.provider.Contacts.Intents.Insert.COMPANY, "organization");

    it.putExtra(android.provider.Contacts.Intents.Insert.EMAIL,"email");

    it.putExtra(android.provider.Contacts.Intents.Insert.PHONE,"homePhone");

    it.putExtra(android.provider.Contacts.Intents.Insert.SECONDARY_PHONE,"mobilePhone");

    it.putExtra( android.provider.Contacts.Intents.Insert.TERTIARY_PHONE,"workPhone");

    it.putExtra(android.provider.Contacts.Intents.Insert.JOB_TITLE,"title");

    startActivity(it);

    //===============================================================

    //19.调用系统编辑添加联系人(全有效):

    Intent intent = newIntent(Intent.ACTION_INSERT_OR_EDIT);

    intent.setType(People.CONTENT_ITEM_TYPE);

    intent.putExtra(Contacts.Intents.Insert.NAME, "My Name");

    intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890");

    intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE,Contacts.PhonesColumns.TYPE_MOBILE);

    intent.putExtra(Contacts.Intents.Insert.EMAIL, "com@com.com");

    intent.putExtra(Contacts.Intents.Insert.EMAIL_TYPE, Contacts.ContactMethodsColumns.TYPE_WORK);

    startActivity(intent);

    //===============================================================

    //20.打开另一程序

    Intent i = new Intent();

    ComponentName cn = new ComponentName("com.example.jay.test",

    "com.example.jay.test.MainActivity");

    i.setComponent(cn);

    i.setAction("android.intent.action.MAIN");

    startActivityForResult(i, RESULT_OK);

    //===============================================================

    //21.打开录音机

    Intent mi = new Intent(Media.RECORD_SOUND_ACTION);

    startActivity(mi);

    //===============================================================

    //22.从google搜索内容

    Intent intent = new Intent();

    intent.setAction(Intent.ACTION_WEB_SEARCH);

    intent.putExtra(SearchManager.QUERY,"searchString")

    startActivity(intent);

    //===============================================================

    1.Intent传递简单数据

    还记得我们在Activity那里学过如何在两个Activity中互相传递简单数据的方法吗?

    就是可以直接通过调用Intent的putExtra()方法存入数据,然后在获得Intent后调用getXxxExtra获得 对应类型的数据;传递多个的话,可以使用Bundle对象作为容器,通过调用Bundle的putXxx先将数据 存储到Bundle中,然后调用Intent的putExtras()方法将Bundle存入Intent中,然后获得Intent以后, 调用getExtras()获得Bundle容器,然后调用其getXXX获取对应的数据! 另外数据存储有点类似于Map的!

    2.Intent传递数组

    嘿嘿,普通类型倒没问题,但是如果是数组咧?解决方法如下:

    写入数组:

    bd.putStringArray("StringArray",newString[]{"呵呵","哈哈"});//可把StringArray换成其他数据类型,比如int,float等等...

    读取数组:

    String[]str =bd.getStringArray("StringArray")

    3.Intent传递集合

    嗯,数组很简单吧,那我们再来传下集合~这个就稍微复杂点了,分情况处理:

    1)List

    写入集合:

    intent.putStringArrayListExtra(name,value)intent.putIntegerArrayListExtra(name,value)

    读取集合:

    intent.getStringArrayListExtra(name)intent.getIntegerArrayListExtra(name)

    2)List< Object>

    将list强转成Serializable类型,然后传入(可用Bundle做媒介)

    写入集合:

    putExtras(key,(Serializable)list)

    读取集合:

    (List)getIntent().getSerializable(key)

    PS:Object类需要实现Serializable接口

    3)Map,或更复杂的

    解决方法是:外层套个List

    //传递复杂些的参数 Mapmap1 =newHashMap();map1.put("key1","value1");map1.put("key2","value2");List>list =newArrayList>();list.add(map1);Intentintent =newIntent();intent.setClass(MainActivity.this,ComplexActivity.class);Bundlebundle =newBundle();//须定义一个list用于在budnle中传递需要传递的ArrayList,这个是必须要的 ArrayListbundlelist =newArrayList();bundlelist.add(list);bundle.putParcelableArrayList("list",bundlelist);intent.putExtras(bundle);startActivity(intent);

    4.Intent传递对象

    传递对象的方式有两种:将对象转换为Json字符串或者通过Serializable,Parcelable序列化 不建议使用Android内置的抠脚Json解析器,可使用fastjson或者Gson第三方库!

    1)将对象转换为Json字符串

    Gson解析的例子:

    Model:

    publicclassBook{privateintid;privateStringtitle;//...}publicclassAuthor{privateintid;privateStringname;//...}

    写入数据:

    Bookbook=newBook();book.setTitle("Java编程思想");Authorauthor=newAuthor();author.setId(1);author.setName("Bruce Eckel");book.setAuthor(author);Intentintent=newIntent(this,SecondActivity.class);intent.putExtra("book",newGson().toJson(book));startActivity(intent);

    读取数据:

    StringbookJson=getIntent().getStringExtra("book");Bookbook=newGson().fromJson(bookJson,Book.class);Log.d(TAG,"book title->"+book.getTitle());Log.d(TAG,"book author name->"+book.getAuthor().getName());

    2)使用Serializable,Parcelable序列化对象

    1.Serializable实现:

    ①业务Bean实现:Serializable接口,写上getter和setter方法

    ②Intent通过调用putExtra(String name, Serializable value)传入对象实例 当然对象有多个的话多个的话,我们也可以先Bundle.putSerializable(x,x);

    ③新Activity调用getSerializableExtra()方法获得对象实例: eg:Product pd = (Product) getIntent().getSerializableExtra("Product");

    ④调用对象get方法获得相应参数

    2.Parcelable实现:

    一般流程:

    ①业务Bean继承Parcelable接口,重写writeToParcel方法,将你的对象序列化为一个Parcel对象;

    ②重写describeContents方法,内容接口描述,默认返回0就可以

    ③实例化静态内部对象CREATOR实现接口Parcelable.Creator

    ④同样式通过Intent的putExtra()方法传入对象实例,当然多个对象的话,我们可以先 放到Bundle里Bundle.putParcelable(x,x),再Intent.putExtras()即可

    一些解释:

    通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射 成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面, 在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的 顺序和读的顺序必须一致。

    实现Parcelable接口的代码示例:

    //Internal Description Interface,You do not need to manage @OverridepublicintdescribeContents(){return0;}@OverridepublicvoidwriteToParcel(Parcelparcel,intflags){parcel.writeString(bookName);parcel.writeString(author);parcel.writeInt(publishTime);}publicstaticfinalParcelable.CreatorCREATOR =newCreator(){@OverridepublicBook[]newArray(intsize){returnnewBook[size];}@OverridepublicBookcreateFromParcel(Parcelsource){BookmBook =newBook();mBook.bookName =source.readString();mBook.author =source.readString();mBook.publishTime =source.readInt();returnmBook;}};

    Android Studio生成Parcleable插件:

    Intellij/Andriod Studio插件android-parcelable-intellij-plugin 只要ALT+Insert,即可直接生成Parcleable接口代码。

    另外:Android中大量用到Parcelable对象,实现Parcable接口又是非常繁琐的,可以用到 第三方的开源框架:Parceler,因为Maven的问题,暂时还没试。

    3.两种序列化方式的比较:

    两者的比较:

    1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。

    2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

    3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的 持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable。

    5.Intent传递Bitmap

    bitmap默认实现Parcelable接口,直接传递即可

    实现代码:

    Bitmapbitmap =null;Intentintent =newIntent();Bundlebundle =newBundle();bundle.putParcelable("bitmap",bitmap);intent.putExtra("bundle",bundle);

    6.传来传去不方便,直接定义全局数据

    如果是传递简单的数据,有这样的需求,Activity1 -> Activity2 -> Activity3 -> Activity4, 你想在Activity中传递某个数据到Activity4中,怎么破,一个个页面传么?

    显然不科学是吧,如果你想某个数据可以在任何地方都能获取到,你就可以考虑使用 Application全局对象了!

    Android系统在每个程序运行的时候创建一个Application对象,而且只会创建一个,所以Application 是单例(singleton)模式的一个类,而且Application对象的生命周期是整个程序中最长的,他的生命 周期等于这个程序的生命周期。如果想存储一些比静态的值(固定不改变的,也可以变),如果你想使用 Application就需要自定义类实现Application类,并且告诉系统实例化的是我们自定义的Application 而非系统默认的,而这一步,就是在AndroidManifest.xml中卫我们的application标签添加:name属性!

    关键部分代码:

    1)自定义Application类:

    classMyAppextendsApplication{privateStringmyState;publicStringgetState(){returnmyState;}publicvoidsetState(Strings){myState =s;}}

    2)AndroidManifest.xml中声明:

    3)在需要的地方调用:

    classBlahextendsActivity{@OverridepublicvoidonCreate(Bundleb){...MyAppappState =((MyApp)getApplicationContext());Stringstate =appState.getState();...}}

    高逼格写法

    :在任何位置都能获取到Application全局对象。

    Applicaiton是系统的一个组件,他也有自己的一个生命周期,我们可以在onCraete里获得这个 Application对象。贴下修改后的代码吧!

    classMyAppextendsApplication{privateStringmyState;privatestaticMyAppinstance;publicstaticMyAppgetInstance(){returninstance;}publicStringgetState(){returnmyState;}publicvoidsetState(Strings){myState =s;}@OverridepublicvoidonCreate(){onCreate();instance =this;}}

    然后在任意地方我们就可以直接调用:MyApp.getInstance()来获得Application的全局对象!

    注意事项:

    Application对象是存在于内存中的,也就有它可能会被系统杀死,比如这样的场景:

    我们在Activity1中往application中存储了用户账号,然后在Activity2中获取到用户账号,并且显示!

    如果我们点击home键,然后过了N久候,系统为了回收内存kill掉了我们的app。这个时候,我们重新 打开这个app,这个时候很神奇的,回到了Activity2的页面,但是如果这个时候你再去获取Application 里的用户账号,程序就会报NullPointerException,然后crash掉~

    之所以会发生上述crash,是因为这个Application对象是全新创建的,可能你以为App是重新启动的, 其实并不是,仅仅是创建一个新的Application,然后启动上次用户离开时的Activity,从而创造App 并没有被杀死的假象!所以如果是比较重要的数据的话,建议你还是进行本地化,另外在使用数据的时候 要对变量的值进行非空检查!还有一点就是:不止是Application变量会这样,单例对象以及公共静态变量 也会这样~

    7.单例模式传参

    上面的Application就是基于单例的,单例模式的特点就是可以保证系统中一个类有且只有一个实例。 这样很容易就能实现,在A中设置参数,在B中直接访问了。这是几种方法中效率最高的。

    范例代码:(代码来自于网上~)

    ①定义一个单例类:

    publicclassXclSingleton{//单例模式实例 privatestaticXclSingletoninstance =null;//synchronized 用于线程安全,防止多线程同时创建实例 publicsynchronizedstaticXclSingletongetInstance(){if(instance ==null){instance =newXclSingleton();}returninstance;}finalHashMapmMap;privateXclSingleton(){mMap =newHashMap();}publicvoidput(Stringkey,Objectvalue){mMap.put(key,value);}publicObjectget(Stringkey){returnmMap.get(key);}}

    ②设置参数:

    XclSingleton.getInstance().put("key1","value1");XclSingleton.getInstance().put("key2","value2");

    该篇是转载了菜鸟教程的intent两篇的总结!!

    展开全文
  • Intent(意图) Intent 是各 组件之间交互 的重要方式,一般用于启动活动、启动服务、发送广播等场景。 作用: 1、指明当前组件想要执行的动作 2、在不同组件之间传递数据 1、显示Intent(明确指出启动的活动,限定...
  • Android Intent传递数据底层分析详细介绍我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法。但是不知各位有没有想过这样一个问题:ActivityB中获取到的对象跟上一个...
  • Android开发人员都知道,Intent适用于在不同的Activity之间传递数据,包括参数、字符串、以及序列化的对象等。那么Intent传输数据的大小有限制吗? 且被限制在1MB左右,不同机型大小不同。当传输的数据超过这个限制...
  • Intent可以携带一些数据,比如基本类型数据int、Boolean,或是String,或是序列化对象,Parcelable与Serializable。Intent传递数据时,如果数据太大,可能会出现异常。比如App闪退,或是Intent发送不成功,logcat...
  • Intent传递数据大小

    2021-01-14 10:02:13
    我们知道可以通过 Intent 和 bundle 在 activity 或 fragment 间进行通信,但是 Intent 传递数据时,如果数据太大,可能会出现异常。
  • 我想通过intent将Object从一个activity传递给另一个 . 但我得到这个错误新哈希0在索引1键为null的数组哈希3552645结束之前活动1:Intent intent = new Intent(Activity1.this, activity2.class);intent.putExtra(...
  • 问题:我们使用 intent 在两个 activity 之间带值跳转的时候,有时候会遇到,接收值的那个 activity收不到 intent 里的数据。解决方法说明:检查自己接收值的那个activity,看一下启动模式,如果是 singleTask 或 ...
  • Intent可以携带一些数据,比如基本类型数据int、Boolean,或是String,或是序列化对象,Parcelable与Serializable。Intent传递数据时,如果数据太大,可能会出现异常。比如App闪退,或是Intent发送不成功,logcat...
  • 使用 Intent 从 MainActivity 跳转到 FirstActivity , 不需要 FirstActivity 回传数据就用 startActivity, val intent = Intent(this, FirstActivity::class.java) intent.putExtra("key_from_main", "data_from_...
  • send_main.xml:receive_main.xml:strings.xml:Intent操作发送Intent的Activity程序。接收Intent的Activity程序。AndroidManifest.xml:Send.java:import android.app.Activity;import android.content.Intent;import ...
  • Intent意图 可用于Activity之间的数据传递,一般可分为下面两种情况,从当前Activity传递到目标Activity后有无返回值:1.传递后无返回值的情况:在起始Activity中,发送数据protectedvoidonCreate...
  • Android开发人员都知道,Intent适用于在不同的Activity之间传递数据,包括参数、字符串、以及序列化的对象等。但是笔者所做的项目用到了使用Intent 传递Bitmap图片对象,图片的数据量相对来说是比较大的,那么intent...
  • 文章目录1、常规Intent传递数据2、Activity启动模式为singleTask时,Intent传递数据 1、常规Intent传递数据 1、MainActivity传参 // Intent构造函数:Intent来源;Intent目的。 Intent intent =new Intent...
  • 我们知道可以通过 Intent 和 bundle 在 activity 或 fragment 间进行通信,但是 Intent 传递数据时,如果数据太大,可能会出现异常。 1. Intent 传递不同大小数据时的问题 Activity间通过Intent传递数据的大小限制 ...
  • 本文实例讲述了Android利用Intent实现数据传递的方法。分享给大家供大家参考,具体如下:在Android开发过程中,很多人都熟悉Intent,这是个用于在多个View之间共享数据的类。本节主要讲述通过点选ListView中的文本,...
  • 1 Android之intent传值的三种方法 (1) startActivity(); (2) startActivityForResult(); (3)3 调用在下个activity自定义的方法"actionStart()",也就是最佳的方法。 2 最常用传值跳转:startActivity()方法 ...
  • 然后声明Intet 以及bundle(存放userDate) 创建的bundle用date.putSerializable()方法存放userdate 在用 intent.putExtras(date)存放bundle public void bindData(FeedVideoDate feedVideoDate) { itemView....
  • 1、BundleBundle是将数据传递到另一个上下文中或保存,或者回复自己状态的数据存储方式,数据不是持久化状态。(1)简单用法//传递参数Intent intentSimple = new Intent();intentSimple.setClass(MainActivity.this,...
  • 1. 基本数据类型 存数据Intent it = new Intent(this, SecondActivity.class); XXX value = xxx; it.putExtra("key", value); startActivity(it); 取数据: int value = getIntent().getXXXExtra("key"); 例如...
  • 我试图通过我的Intent数据传递到下一个活动,这样我就可以收到它并给出一个计时器值.Button TimerButton = (Button)findViewById(R.id.TimerActivityButton);TimerButton.setOnClickListener(new View....
  • onActivityResult()Intent数据始终为null 应该在onPause,onStop,onDestroy,finish…等之前调用setResult
  • 注:此方法适用于 Autojs 4.0.3 Alpha4 及以上版本,其他版本可通过该方法实现前言如果曾看过这文章的读者,应该知道 Tasker 可以通过构造 JavaScript 模块文件向 Autojs 传递数据,虽然该方法很方便与灵活,但其...
  • Intent中可以存放bundle类型数据,而bundle数据可以用来保存键值对数据,还可以保存数组,在进程通信中来传数据很方便,但是需要注意,intent的传送的本质是binder方式,这就决定了不能用来传送大数据量的数据,不然...
  • Intent传递数据 向下一个Activity传递数据 Intent提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出就可以了。 button....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 156,101
精华内容 62,440
关键字:

intent传数据