Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the methods of data transfer between AndroidActivity

2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail what the data transfer methods between AndroidActivity are, and the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.

Preface

The data transferred between Activity is generally relatively simple, but sometimes some more complex data will be transferred in the actual development, so we can learn more ways to transfer data between Activity.

1. Pass through Intent

When we do Activity jump, we need to have Intent. At this time, Intent can carry data, and we can use it to transfer data to other Activity. Intent should be the widest type of support and the most comprehensive delivery mode provided by the system. Basic data types, complex data types (such as arrays, collections), custom data types, and so on are supported and are not complex to use. Each of these methods will be described below.

1.1. Basic data type transfer

String is not a basic data type. There are only 8 basic data types of Java, which are well supported by Intent. These eight basic types have their own wrapper types (Wrap Class, complex types), and the wrapper type also implements the Serializable interface (later), so that Intent can also well support the wrapper type. The corresponding relationships between the 8 basic types and their packaging classes are as follows:

Let me cook a chestnut:

Suppose there are two Activity; of Activity1,Activity2. If you want to start Activity2 in Activity1 and pass several basic types of data, you can write this:

Intent intent = new Intent (this, Activity2.class); intent.putExtra (String name, boolean value); intent.putExtra (String name, byte value); intent.putExtra (String name, char value); intent.putExtra (String name, short value); intent.putExtra (String name, int value); intent.putExtra (String name, float value); intent.putExtra (String name, long value); intent.putExtra (String name, double value); startActivity (intent)

It can be received in the onCreate of Activity2 in the following ways:

Intent intent = getIntent (); boolean bool = intent.getBooleanExtra (String name, boolean defaultValue); byte bt = intent.getByteExtra (String name, byte defaultValue); char ch = intent.getCharExtra (String name, char defaultValue); short sh = intent.getShortExtra (String name, short defaultValue); int I = intent.getIntExtra (String name, int defaultValue); float fl = intent.getFloatExtra (String name, float defaultValue); long lg = intent.getLongExtra (String name, long defaultValue); double db = intent.getDoubleExtra (String name, double defaultValue)

PS: when sending and receiving above, the same field must use the same name, for example: intent.putExtra ("BOOLEAN", true); intent.getBooleanExtra ("BOOLEAN", false)

1.2. Complex data type transfer

Some common complex types are also defined in Java, such as String, arrays of basic data types, ArrayList, HashMap, and so on. Intent also supports them, which makes it easy for us to pass these complex types through Intent. The method is similar to the above basic types, such as:

Intent.putExtra (String name, String value); intent.putExtra (String name, int [] value); intent.putExtra (String name, Parcelable value); intent.putExtra (String name, Serializable value); intent.putExtra (String name, CharSequence value); intent.putStringArrayListExtra (String name, ArrayList value)

The way of receiving is similar, so I won't list them one by one here.

However, data structures of complex types can also be stored in themselves, such as ArrayList and HashMap, and if you want to pass them through Intent, you have to make sure that the types stored inside them can also support serialization and deserialization.

1.3. Custom data type transfer

Many types supported by Intent have been listed above, but these types provided by default are not enough. Very often, we will define our own data types, such as defining a Student:

Public class Student {public String name; public int age;}

So how should we pass it on through Intent at this time?

1.3.1. Implement Serializable interface

Let's first take a look at the implementation of complex data types provided by default and supported by Intent:

Public final class String implements java.io.Serializable, Comparable, CharSequencepublic class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializablepublic class HashMap extends AbstractMap implements Map, Cloneable, Serializable

We can see that they all have a common feature: implement the Serializable interface.

Serializable is an empty interface that does not define any methods, and knowledge is used to mark that its implementation classes support serialization and deserialization.

So when we want the custom type to be passed through Intent, we just need to let the class implement the Serializable interface.

Still use Student to cook a chestnut:

Public class Student implements Serializable {private static final long serialVersionUID = 1L; public String name; public int age;}

The delivery method is:

Intent.putExtra (String name, Serializable value); intent.getSerializableExtra (String name)

PS: there are also some knowledge points about Serializable, such as serialVersionUID, static variable serialization, transient keyword, inheritance issues, etc., which will not be introduced here, and those who are interested can check it out on their own.

1.3.2. Implement Parcelable interface

The Serializable interface is introduced above, but Serializable is the implementation of Java. It can be used normally under Android, and there is nothing wrong with it. However, Google feels that Serializable is not efficient enough when Android memory is small and performance is not strong, so a special interface-Parcelable is tailored for Android. Or use Student to cook chestnuts:

To implement the Parcelable interface, you just need to write the Student class and properties, then let Student implement Parcelable, and then follow AS's two-step hint: the first step is to rewrite describeContents and writeToParcel, and the second step is to create CREATOR. The written classes are as follows:

Public class Student implements Parcelable {public String name; public int age; protected Student (Parcel in) {name = in.readString (); age = in.readInt ();} public static final Creator CREATOR = new Creator () {@ Override public Student createFromParcel (Parcel in) {return new Student (in);} @ Override public Student [] newArray (int size) {return new Student [size];}}; @ Override public int describeContents () {return 0 } @ Override public void writeToParcel (Parcel dest, int flags) {dest.writeString (name); dest.writeInt (age);}}

At this point, you can use the following methods to pass through Intent:

Intent.putExtra (String name, Parcelable value); intent.getParcelableExtra (String name)

Principles for the use of these two methods of serialization:

1) when using memory, Parcelable has higher performance than Serializable, so Parcelable is recommended.

2) Serializable generates a large number of temporary variables during serialization, resulting in frequent GC.

3) Parcelable cannot be used when the data is to be stored on disk, because Parcelable cannot ensure the persistence of the data in the event of external changes. Although Serializable is less efficient, Serializable is recommended at this time.

PS:Intent also supports encapsulating data through Bundle, and then passing Bundle, but if we look at the implementation of intent.putExtra, we will find that the interior of intent.putExtra is also a Bundle maintained. Therefore, the data put in through putExtra can also be fetched through Bundle when taken out.

2. Pass through global variables

As the name implies, it is to transfer data with the help of a global variable. Again, take the previous two Activity as examples, passing Student objects that do not support serialization. We can create a utility class first, such as:

Public class Transmitter {public static Student student;}

Then when delivering and receiving, you can do this:

/ / pass Student stu = new Student (); Transmitter.student = stu;Intent intent = new Intent (this, Activity2); startActivity (intent); / / receive onCreate (...) {Student stu = Transmitter.student;}

You can see that it is very convenient and quick to use.

However, global variables always exist during the operation of APP, if the amount of data stored through global variables is relatively large and the number of variables is large, and after not using it, the global variable is not set to null in time so that GC can recycle it, then it may cause OOM problems.

Therefore, if you want to use global variables as a data transfer method, you must pay attention to maintaining the state of these global variables.

3. Pass through SharedPreferences

SharedPreferences is a way of data storage provided by Android. It can store data in xml format in the machine. It is usually used to store the setting information of APP, and we can also use it to realize the data transfer between Activity.

However, because of its special way of working, SharedPreferences only provides operations on some basic types and String, and does not support other existing complex types and custom types. The only types it supports are:

BooleanfloatintlongStringSet

Still cook the chestnuts with the previous two Activity. To transfer data between them, you just need to put the data in the Activity1 and put the data into the SharedPreferences, as follows:

SharedPreferences sp = getSharedPreferences ("FILENAME", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit (); editor.putBoolean (String key, boolean value); editor.putFloat (String key, float value); editor.putInt (String key, int value); editor.putLong (String key, long value); editor.putString (String key, String value); editor.putStringSet (String key, Set values); / / editor.commit (); editor.apply (); startActivity (...)

Then extract the data from Activity2 through SharedPreferences, as follows:

SharedPreferences sp = getSharedPreferences ("FILENAME", MODE_PRIVATE); sp.getBoolean (String key, boolean defValue); sp.getFloat (String key, float defValue); sp.getInt (String key, int defValue); sp.getLong (String key, long defValue); sp.getString (String key, String defValue); sp.getStringSet (String key, Set defValue)

There are a few things to note about SharedPreferences:

1. GetSharedPreferences ("FILENAME", MODE_PRIVATE) is called through Context, and the FILENAME and MODE_PRIVATE sent and received should be consistent.

2. When sending, after storing data in SharedPreferences, you need to submit it in two ways: commit and apply. The difference between the two is as follows: commit: synchronize operation, write changes to Storage immediately, and return value of boolean type.

Apply: immediately refresh the data in In-memory, and then start an asynchronous task to write changes to Storage, with no return value.

When two apply operate at the same time, the later call to apply will be saved to the Storage; when there is an apply in progress, the call to commit,commit will be blocked until the apply is finished.

Because Android framework has done everything, we can use commit unconditionally instead of apply when we don't need to pay attention to the return value of the commit operation, and AS will suggest replacing commit with apply.

3. All the data types supported by SharedPreferences must support serialization operations. The Set mentioned above is an interface, so we can not instantiate it directly, but we can use its direct or indirect implementation classes, such as HashSet, TreeSet, LinkedHashSet, and so on.

When we look at these implementations, it is not difficult to find that they also implement the Serializable interface and support serialization operations:

Public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializablepublic class TreeSet extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializablepublic class LinkedHashSet extends HashSet implements Set, Cloneable, java.io.Serializable {

4. Pass through SystemProperties

This class can be thought of as a class that maintains global variables, except that the global variables here are systematic and their values are the contents of the build.prop file. Let's take a look at its definition:

/ * Gives access to the system properties store. The system properties * store contains a list of string key-value pairs. * * {@ hide} * / public class SystemProperties

Yes, this thing is a hide class, which means that normally it is not available in SDK, nor can it be accessed in AS. However, we can still access it through some means, such as reflection, exporting the library of source code to AS, compiling APP in source code, and so on.

Instead of focusing on how to access it here, we focus on using it for data transfer between Activity.

Suppose we compile in the source code, or cook chestnuts with the first two Activity. You can do this when sending data:

SystemProperties.set ("NAME", "Shawn.XiaFei"); startActivity (...)

When receiving, you can write:

SystemProperties.get ("NAME"); / or SystemProperties.get ("NAME", "defValue")

Isn't it convenient, but take it easy, let's take a look at the implementation of set:

/ * Set the value for the given key. * @ throws IllegalArgumentException if the key exceeds 32 characters * @ throws IllegalArgumentException if the value exceeds 92 characters * / public static void set (String key, String val) {if (key.length () > PROP_NAME_MAX) {throw new IllegalArgumentException ("key.length >" + PROP_NAME_MAX);} if (val! = null & & val.length () > PROP_VALUE_MAX) {throw new IllegalArgumentException ("val.length >" + PROP_VALUE_MAX);} native_set (key, val);}

Look at the notes, yes, key and val both limit the length! Of course, 32 and 92 characters are good enough under normal circumstances. But here's what the average APP developer might not be able to do.

As mentioned earlier, this thing is invisible to SDK, and it maintains the property values of the system, which can be read by APP, but cannot be easily modified. Therefore, in the case of set above, the following error will be reported if the permissions are insufficient:

Unable to set property "NAME" to "Shawn.XiaFei": connection failed; errno=13 (Permission denied) type=1400 audit (0.0virtual 167): avc: denied {write} for name= "property_service" dev= "tmpfs" ino=10696 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:property_socket:s0 tclass=sock_file permissive=0

This error is common in Rom development, and the solution is to configure the appropriate avc permissions, which is beyond the reach of the average APP developer. Those who are interested can check the information by themselves, and there is no introduction here.

5. Pass through SettingsProvider

Fussy people may have noticed that there is usually an application on Android devices that maintains some system configuration information through a database. In Rom development, it is usually used to set the default behavior for the first boot.

The key to passing data through it is the android.provider.Settings class, which has three commonly used static inner classes, namely: Global, System, and Secure, which correspond to different permission levels.

Boiled chestnuts:

When sending, just write:

/ * Settings.System.putInt (ContentResolver cr, String name, int value); Settings.System.putString (ContentResolver cr, String name, String value); Settings.System.putFloat (ContentResolver cr, String name, float value); Settings.System.putLong (ContentResolver cr, String name, long value); * / Settings.Global.putString (getContentResolver (), "NAME", "Shawn.XiaFei"); startActivity (...)

When receiving, write like this:

String name = Settings.Global.getString (getContentResolver (), "NAME")

It is also very easy to use! However, although it is easy to use, it is not so easy. It also needs permission!

If there are not enough permissions, the following error will be reported at run time:

Java.lang.RuntimeException: Unable to start activity ComponentInfo {xxx.xxx/xxx.xxx.Activity1}: java.lang.SecurityException: writing to settings requires:android.permission.WRITE_SECURE_SETTINGSat android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2805) at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2883) at android.app.ActivityThread.-wrap11 (Unknown Source:0) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1613) at android.os.Handler.dispatchMessage (Handler.java:106) At android.os.Looper.loop (Looper.java:164) at android.app.ActivityThread.main (ActivityThread.java:6523) at java.lang.reflect.Method.invoke (Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:857)

The meaning is very clear. We have to give it the permission to WRITE_SECURE_SETTINGS. Let's try to add it to Manifest. As a result, AS turns red. The prompt is as follows:

Permissions with the protection level signature or signatureOrSystem are only granted to system apps. If an app is a regular non-system app, it will never be able to use these permissions.

That is to say, this permission can only be obtained by the system APP, and there is no chance of the tripartite APP.

6. Pass through the database

In fact, the SettingsProvider method introduced above is also implemented through the database, but it encapsulates the operation of the database and we can't feel it. Such being the case, we can also create a database in our own APP, and then transfer data between Activity through the database. Chestnuts cook too much, can not eat, do not cook, interested can check the knowledge of the database.

7. Transfer by file

The SharedPreferences mentioned earlier is also implemented on a file basis, except that SharedPreferences is fixed in xml format. We can also customize the file operation mode to achieve data access, and then achieve data transfer between Activity. I said that the chestnuts would not be cooked, so if you are interested, check it out for yourself.

In fact, there are still many methods of data transmission between Activity, each has its own advantages and disadvantages, but the most commonly used one is the first one-- Intent. Other methods are feasible in theory, but they will be a little chicken rib in practice, or the loss outweighs the gain.

Therefore, if you want to master the skills of data transmission between Activity, I think you only need to master the usage of Intent, be able to use it skillfully, and handle OK flexibly. As for other methods, it is enough to be able to describe the principle.

This is the end of the sharing of data transfer methods between AndroidActivity. I hope the above content can be of some help to you and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report