English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Dieser Artikel behandelt detailliert die komplexen Übermittlungsmethoden von Android Intents und wird hier geteilt, um zur Referenz zu dienen:
Intent ist das Medium zur Übermittlung von Parametern zwischen Activity und Activity, zwischen Activity und Service, und diese beiden realisieren in der Regel die Übermittlung von Java-Grundobjekttypen und Strings.
In der Praxis gibt es beim Übertragen von Werten zwischen Seiten häufig Bedarf an der Übermittlung von Object-Objekten, List-Typen, List<Object>-Typen und globalen Variablen usw. Dieser Artikel beschreibt, wie man diese Arten von Parametern überträgt.
1. Übermittlung von List<String> und List<Integer>
Hier wird ein Beispiel zur Übermittlung von List<String> gezeigt, die Syntax zum Senden von List<String> ist:
intent.putStringArrayListExtra(key, list);
Die Syntax zum Empfangen von List<String> ist:
list = (ArrayList<String>)getIntent().getStringArrayListExtra(key);
Hier ist ein Beispielanwendung:
// =============Senden von List<String>============= ArrayList<String> stringList = new ArrayList<String>(); stringList.add("string"1"); stringList.add("string"2"); stringList.add("string"3"); Intent intent = new Intent(); intent.setClass(ListDemoActivity.this, StringListActivity.class); intent.putStringArrayListExtra("ListString", stringList); startActivity(intent); // ====================Empfangen von List<String>====================== ArrayList<String> stringList = (ArrayList<String>) getIntent().getStringArrayListExtra("ListString");
Ähnliche Operationen wie List<Integer> können auch durch die folgenden Methoden realisiert werden:
intent.putIntegerArrayListExtra(key, list); list = (ArrayList<Integer>) getIntent().getIntegerArrayListExtra(key);
Zwei: Übertragung von Object durch Serializable und Parcelable
Es gibt zwei Methoden, um Objekte zwischen Android-Intents zu übertragen: eine ist Bundle.putSerializable(Key, Object); und die andere ist Bundle.putParcelable(Key, Object). Das Object im Methodenaufruf muss bestimmte Bedingungen erfüllen: Der erste implementiert das Serializable-Interface, und der zweite implementiert das Parcelable-Interface.
Hier ist die User-Klasse, die das Serializable-Interface implementiert, benannt als SerializableUser. Der NameSerializableUser wurde nur aus Gründen der Unterscheidung zwischen der ParcelableUser-Klasse, die das Parcelable-Interface implementiert, gewählt. In der tatsächlichen Entwicklung wird diese Namensgebung nicht empfohlen:
public class SerializableUser implements Serializable { private String userName; private String password; public SerializableUser() { } public SerializableUser(String userName, String password) { this.userName = userName; this.password = password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
Hier ist die User-Klasse, die das Parcelable-Interface implementiert:
public class ParcelableUser implements Parcelable { private String userName; private String password; public ParcelableUser() { } public ParcelableUser(String userName, String password) { this.userName = userName; this.password = password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public static final Parcelable.Creator<ParcelableUser> CREATOR = new Creator<ParcelableUser>() { @Override public ParcelableUser createFromParcel(Parcel source) { ParcelableUser parcelableUser = new ParcelableUser(); parcelableUser.userName = source.readString(); parcelableUser.password = source.readString(); return parcelableUser; } @Override public ParcelableUser[] newArray(int size) { return new ParcelableUser[size]; } }; @Override public int describeContents() { // 待办 自动-生成的方法存根 return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // 待办 自动-生成的方法存根 dest.writeString(userName); dest.writeString(password); } }
使用两种方式传递语法分别为:
bundle.putSerializable(key,object); bundle.putParcelable(key,object);
使用两种方式接收语法分别为:
object=(Object) getIntent().getSerializableExtra(key); object = (Object) getIntent().getParcelableExtra(key);
// ==========Mit Serializable und Parcelable Object senden=========== SerializableUser serializableUser = new SerializableUser("user"1", "123456"); ParcelableUser parcelableUser = new ParcelableUser("user"2""654321"); Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putSerializable("serializableUser", serializableUser); bundle.putParcelable("parcelableUser", parcelableUser); intent.setClass(ListDemoActivity.this, ObjectActivity.class); intent.putExtras(bundle); startActivity(intent); // ====================Object empfangen====================== SerializableUser serializableUser = (SerializableUser) getIntent().getSerializableExtra("serializableUser"); ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");
Vielleicht haben einige bemerkt, dass das Implementieren des Serializable-Interfaces bedeutet, ein Objekt zu serialisieren und es dann zu übertragen, was mit der gängigen Java-Programmierung nicht unbedingt eine klare Unterscheidung gibt und der User keine明显的 Änderungen vornehmen muss, was einfach ist. Ich empfehle auch diese Methode.
Allerdings ist die Implementierung des Parcelable-Interfaces für das letztere etwas komplexer. Was ist das Parcelable-Interface?
Android bietet einen neuen Typ: Parcel, der als Behälter für Daten verwendet wird, um Daten zu verpacken, und verpackte Daten können über Intent oder IPC übertragen werden. Neben den grundlegenden Typen können nur Klassen, die das Parcelable-Interface implementieren, in Parcel eingefügt werden.
Die Implementierung des Parcelable-Interfaces erfordert die Implementierung von drei Methoden:
1)Die Methode writeToParcel. Diese Methode schreibt die Daten der Klasse in das externe bereitgestellte Parcel.
Die Deklaration: writeToParcel(Parcel dest, int flags).
2)Die Methode describeContents. Es genügt, 0 zurückzugeben.
3)Der statische Parcelable.Creator<T>-Interface, dieses Interface hat zwei Methoden:
createFromParcel(Parcel in) implementiert die Funktion, ein Instanz des Klassen aus in zu erstellen.
newArray(int size) erstellt ein Array vom Typ T mit einer Länge von size. return new T[size]; genügt. Diese Methode ist für die Deserialisierung von Arrays durch externe Klassen vorgesehen.
Durch die Ausgabe im Log können wir den Lauf der Anwendung überprüfen. Beim Aufruf von bundle.putParcelable("parcelableUser", parcelableUser); wird die Methode public void writeToParcel(Parcel dest, int flags) der Klasse ParcelableUser aufgerufen, und Daten werden in dest geschrieben. Beim ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser"); wird die Methode public ParcelableUser createFromParcel(Parcel source) der Klasse ParcelableUser aufgerufen, um ein ParcelableUser-Objekt zu erstellen und den Attributen dieses Objekts Werte zuzuweisen. Hierbei sind Parcel source und Parcel dest identisch, und dann wird dieses ParcelableUser-Objekt zurückgegeben. Schließlich können die Attribute von parcelableUser ausgegeben werden.
Drei: Übermittlung von List<Object>
Wenn wir eine Liste von Object, d.h. List<Object>, übermitteln möchten, wie sollten wir dann vorgehen? Zunächst muss das Object-Objekt das Serializable-Interface implementieren, dann muss die Liste in den Typ Serializable umgewandelt werden, und schließlich:
Intent.putExtra(key, (Serializable)objectList);
Diese Syntax wird verwendet, um zu übermitteln, und der Empfangende muss bei der Empfangnahme eine explizite Typkonvertierung zu List<Object> durchführen. Die Syntax zum Empfangen von List<Object> ist: }}
objectList= (List<Object>) getIntent().getSerializableExtra(key);
Hier ist ein Anwendungsbeispiel. Die SerializableUser-Klasse, die im vorherigen Schritt vorgestellt wurde, wird hier nicht noch einmal angegeben.
// ==============Senden von List<Object>=========== SerializableUser user1 = new SerializableUser("user1", "123456"); SerializableUser user2 = new SerializableUser("user2", "654321"); List<SerializableUser> objectList = new ArrayList<SerializableUser>(); objectList.add(user1); objectList.add(user2); Intent intent = new Intent(); intent.setClass(ListDemoActivity.this, ObjectListActivity.class); intent.putExtra("ListObject", (Serializable) objectList); startActivity(intent); // ====================Empfangen von List<Object>====================== List<SerializableUser> objectList = (List<SerializableUser>) getIntent().getSerializableExtra("ListObject");
Vier, globale Variablen
Wenn einige spezielle parameter auf Anwendungsebene nicht bequem mit intent übermittelt werden können, denken wir schnell daran, ob globale Variablen oder statische Variablen verwendet werden können? Java statische Variablen sind hier geeignet, aber ihr Wert geht verloren, wenn Activitys System.exit(0) oder finish() aufrufen.
In Android gibt es eine elegantere Methode, die ApplicationContext zu verwenden. Diese Methode zur Verwaltung globaler Variablen ist sicherer als statische Klassen und wird erst freigegeben, wenn alle Activitys der Anwendung destroyed wurden.
Der SDK von Android erwähnt, dass eine Anwendung (Application) verwendet wird, um globale Variablen zu speichern und existiert bereits beim Erstellen des Pakets. Daher müssen wir nicht mehr wie J2SE那样需要创建public权限的static变量,而直接在application中去实现。只需要调用Context的 getApplicationContext或者Activity的getApplication方法来获得一个Application对象,就可以设置或读取全局变量的值。
启动Application时,系统会创建一个PID,即进程ID,所有的Activity就会在此进程上运行。那么我们在Application创建的时候初始化全局变量,同一个应用的所有Activity都可以取到这些全局变量的值,换句话说,我们在某一个Activity中改变了这些全局变量的值,那么在同一个应用的其他Activity中值就会改变。
用法:
1创建一个属于你自己的android.app.Application的子类,为想要共享的private全局变量添加setter和getter方法。
public class MyApp extends Application{ private String globalVariable; public String getGlobalVariable() { return globalVariable; } public void setGlobalVariable(String globalVariable) { this.globalVariable = globalVariable; } }
2在manifest中声明一下这个类,这时Android就为此创建一个全局可用的实例。
其实就是在原来仅有的一个application标签上为application指定一个名字为这个全局实例。
<application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name">
3可以在其他任何地方使用Context.getApplicationContext()方法获取这个实例,进而获取其中的状态(变量)。
// ============使用全局变量传递参数============== MyApp myApp = ((MyApp) getApplicationContext());//Erhalten Sie unsere Anwendung MyApp myApp.setGlobalVariable("globale Variable"); Intent intent = new Intent(); intent.setClass(ListDemoActivity.this, GlobalActivity.class); startActivity(intent); // ============ Parameter für globale Variablen empfangen ============ MyApp myApp = ((MyApp) getApplicationContext()); String globalVariable = myApp.getGlobalVariable();
Interessierte Leser, die mehr über Android-Themen erfahren möchten, können die Themenbereiche dieser Website besuchen: 'Android-Entwicklung Einführung und Fortgeschrittene Anleitungen', 'Aktivitäts-Operationstipps der Android-Programmierung', 'Übersicht über die Ressourcenoperationen von Android', 'Übersicht über die Dateioperationen von Android', 'Übersicht über die SQLite-Datenbankoperationen von Android', 'Übersicht über die JSON-Datenoperationen von Android', 'Übersicht über die Datenbankoperationen von Android', 'Übersicht über die SD-Karte Operationen der Android-Programmierung', 'Übersicht über die View-Techniken von Android' und 'Übersicht über die Verwendung der Android-Kontrollen'.
Ich hoffe, dass die in diesem Artikel beschriebenen Inhalte Ihnen bei der Android-Programmgestaltung helfen.
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet entnommen und gehört dem jeweiligen Urheber. Der Inhalt wurde von Internetbenutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht von Hand bearbeitet. Diese Website übernimmt keine rechtlichen Verantwortlichkeiten. Wenn Sie verdächtige Inhalte entdecken, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @ beim Senden einer E-Mail zur Meldung von Verstößen und fügen Sie relevante Beweise bei. Bei nachgewiesener Verletzung wird diese Website die beanstandeten Inhalte sofort löschen.)