English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Android intent間の複雑なパラメータの伝達方法の詳細

この記事では、Androidのintent間の複雑なパラメータ伝達方法を詳細に説明します。以下にその詳細を共有します:

IntentはActivityとActivity、ActivityとService間でパラメータを伝達するメディアであり、これらは通常Javaの基本オブジェクトタイプとStringの伝達を実現しています。
実際のプロジェクトでは、ページ間の値の伝達に加えて、Objectオブジェクト、Listタイプ、List<Object>タイプ、グローバル変数など、多くの必要があります。この記事では、これらのタイプのパラメータをどう伝達するかを説明します。

一、List<String>とList<Integer>の送信

以下でList<String>の送信例を示します。送信文法は以下の通りです:

intent.putStringArrayListExtra(key, list);

List<String>の受け取り文法は以下の通りです:

list = (ArrayList<String>)getIntent().getStringArrayListExtra(key);

以下はその使用例です:

// =============送信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);
// ====================受け取るList<String>======================
ArrayList<String> stringList = (ArrayList<String>) getIntent().getStringArrayListExtra("ListString");

List<Integer>などの操作は以下のメソッドを呼び出して、送信と受信を実現できます:

intent.putIntegerArrayListExtra(key, list);
list =(ArrayList<Integer>) getIntent().getIntegerArrayListExtra(key);

二、SerializableとParcelableの二つの方法を使用してObjectを伝搬する

AndroidのIntent間でのオブジェクトの伝搬には、二つの方法があります。一つはBundle.putSerializable(Key,Object);、もう一つはBundle.putParcelable(Key,Object);です。メソッド内のObjectは特定の条件を満たす必要があり、前者はSerializableインターフェースを実装し、後者はParcelableインターフェースを実装しています。

以下はSerializableインターフェースを実装したUserクラスで、SerializableUserと名付けられているのは、Parcelableインターフェースを実装したUserクラスと区別するためです。実際の開発ではこのような命名は推奨されません:

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;
  }
}

以下はParcelableインターフェースを実装したUserクラスです:

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() {
    // TODO 自動-生成されたメソッドスタブ
    return 0;
  }
  @Override
  public void writeToParcel(Parcel dest, int flags) {
    // TODO 自動-生成されたメソッドスタブ
    dest.writeString(userName);
    dest.writeString(password);
  }
}

二つの方法で使用伝送の文法は以下の通りです:

bundle.putSerializable(key,object);
bundle.putParcelable(key,object);

二つの方法で使用受信の文法は以下の通りです:

object=(Object) getIntent().getSerializableExtra(key);
object = (Object) getIntent().getParcelableExtra(key);
// ==========SerializableとParcelableを使用してObjectを送信することを区別します===========
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の受信======================
SerializableUser serializableUser = (SerializableUser) getIntent().getSerializableExtra("serializableUser");
ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");

実装Serializableインターフェースは、オブジェクトをシリアライズしてから伝播することであり、Javaの一般的なプログラミングとは明らかな違いがなく、Userは明らかに変更する必要がありません。簡単です。この方法を推奨します。

しかし、Parcelableインターフェースを実装する後者のクラスは比較的複雑です。Parcelableとは何ですか?

Androidは新しいタイプ:Parcelを提供しており、データを封装するコンテナとして使用されます。封装されたデータはIntentやIPCを通じて伝播できます。基本的なタイプ以外は、Parcelableインターフェースを実装したクラスのみがParcelに格納できます。

Parcelableインターフェースを実装するには、3つのメソッドを実装する必要があります:

1)writeToParcelメソッド。このメソッドは、クラスのデータを外部が提供するParcelに書き込みます。
宣言:writeToParcel(Parcel dest, int flags)。

2)describeContentsメソッド。0を直接返せば良いです。

3)静的Parcelable.Creator<T>インターフェース、このインターフェースには2つのメソッドがあります:

createFromParcel(Parcel in)は、inからクラスのインスタンスを作成する機能を実装します。
newArray(int size)は、型がTで長さがsizeの配列を作成します。return new T[size];でできます。このメソッドは外部クラスが本クラスの配列を反序列化するために使用されます。

logテスト出力からプログラムの実行状況がわかります。bundle.putParcelable("parcelableUser", parcelableUser);のとき、ParcelableUserクラスのpublic void writeToParcel(Parcel dest, int flags)メソッドが呼び出され、destにデータを書き込みます。ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");のとき、ParcelableUserクラスのpublic ParcelableUser createFromParcel(Parcel source) メソッドが呼び出され、ParcelableUserオブジェクトが作成され、その属性に値が設定されます。ここでのParcel sourceとParcel destは同じです。その後、ParcelableUserオブジェクトを返します。最後にparcelableUserの属性情報を出力できます。

三、List<Object>の伝達

もし渡すのはObjectで構成されたListリスト、すなわちList<Object>の場合はどうしますか?まず、ObjectオブジェクトがSerializableインターフェースを実装していることを確認し、リストをSerializableタイプに強制変換して、以下のように:

Intent.putExtra(key, (Serializable)objectList);

このような文法で渡され、受け取る側もList<Object>に強制型変換する必要があります。List<Object>を使用する文法は:}}

objectList= (List<Object>) getIntent().getSerializableExtra(key);

以下はアプリケーションの例です。ここで使用するSerializableUserクラスは前の手順で示されましたので、ここでは再び示しません。

// ==============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);
// ====================List<Object>の受信======================
List<SerializableUser> objectList = (List<SerializableUser>) getIntent().getSerializableExtra("ListObject");

四、グローバル変数

特定のアプリケーションレベルのパラメータがintentを使用してパラメータを渡すのに不便な場合、グローバル変数や静的変数を使用できないかとすぐに思いつくでしょう。Javaの静的変数はここに適していますが、ActivityがSystem.exit(0)やfinish()を呼び出した後には値が失われます。

そして、androidでは、ApplicationContextを使用する方がより洗練された方法があります。このグローバル変数の方法は、静的クラスよりもより保障が高く、アプリケーションのすべてのActivityがdestoryされるまで解放されません。

AndroidのSDKには、Applicationがグローバル変数を保存するために使用され、packageが作成されたときから存在するという記述があります。したがって、グローバル変数を作成する必要がある場合、Jのように再び行う必要はありません。2SEのようにpublic権限のstatic変数を作成する必要がある場合、application内で直接実装します。Applicationオブジェクトを取得するためにContextのgetApplicationContextまたはActivityのgetApplicationメソッドを呼び出すだけで、グローバル変数の値を設定または読み取ることができます。

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());//私たちのアプリケーションMyAppを取得します
myApp.setGlobalVariable("全般変数");
Intent intent = new Intent();
intent.setClass(ListDemoActivity.this, GlobalActivity.class);
startActivity(intent);
// ============全般変数の引数を受け取る============
MyApp myApp = ((MyApp) getApplicationContext());
String globalVariable = myApp.getGlobalVariable();

Androidに関するさらに詳しい内容に興味がある読者は、このサイトの特集を確認してください:《Android開発入門と進階教程》、《Androidプログラミングにおけるactivity操作の技術的な要約》、《Androidリソース操作の技術的な要約》、《Androidファイル操作の技術的な要約》、《AndroidSQLiteデータベース操作の技術的な要約》、《Androidjson形式データ操作の技術的な要約》、《Androidデータベース操作の技術的な要約》、《Androidプログラミング開発におけるSDカード操作の方法の要約》、《AndroidビューViewの技術的な要約》および《Androidコントロールの使用方法の要約》

この記事で述べたことが皆様のAndroidプログラムデザインに役立つことを願っています。

声明:この記事の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーにより自発的に貢献し、自己でアップロードされています。このサイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害が疑われる内容がある場合は、メールを送信してください:notice#oldtoolbag.com(メールを送信する際には、#を@に変更してください。届出を行い、関連する証拠を提供してください。一旦確認がついたら、このサイトは即座に侵害される内容を削除します。)

おすすめ