インテントによる複雑なデータの配信
このセクションの紹介:
前のセクションでは、インテントの基本的な使用法をいくつか学び、インテントの 7 つのプロパティ、明示的なインテント、およびインテントについて学びました。 暗黙的インテントと暗黙的インテントをカスタマイズする方法、そして最後に、一般的に使用されるシステム インテントをいくつか紹介します。 このセクションでは、インテントがデータを渡す問題について説明します~よし、このセクションを始めましょう~
1. インテントは単純なデータを渡します
アクティビティ A の方法で 2 つのアクティビティで相互に通信する方法を学習したことを思い出してください。単純なデータを渡すには?
インテントの putExtra() メソッドを呼び出してデータを直接保存し、インテントを取得した後に getXxxExtra を呼び出すことができます。 対応するデータのタイプが複数渡される場合は、Bundle オブジェクトをコンテナとして使用し、最初に Bundle の putXxx を呼び出してデータを転送できます。 それをバンドルに格納し、インテントの putExtras() メソッドを呼び出してバンドルをインテントに格納し、インテントを取得した後、 getExtras() を呼び出してバンドル コンテナを取得し、次にその getXXX を呼び出して対応するデータを取得します。 さらに、データ ストレージは Map の <key, value> に似ています。
2. インテントは配列を渡します
ふふ、通常の型は問題ありませんが、配列の場合はどうでしょうか?解決策は次のとおりです:
配列に書き込みます:
//StringArray は次のように置き換えることができます。 int、float などの他のデータ型...
配列を読み取ります:
3。
まあ、配列 それは非常に単純です。それでは、もう一度コレクションを渡しましょう~これは少し複雑で、状況に応じて処理されます:
1) リスト<基本データ型または文字列>
を書きますコレクション:
コレクションの読み取り:
2) List< Object> ;
リストを Serializable 型にして渡します (Bundle をメディアとして使用できます)
コレクションを書き込みます:
コレクションを読み取ります:
追記: Object クラスは Serializable インターフェイスを実装する必要があります
3) Map<String、Object>、またはより複雑な
解決策は次のとおりです: 外側の層に List を置きます
Map
map1.put("key2", "value2");
List
インテント = new Intent(); MainActivity.this ,ComplexActivity.class);
Bundlebundle = new Bundle();
//バンドルで渡す必要がある ArrayList<Object> を渡すためのリストを定義する必要があります
ArrayList Bundlelist = new ArrayList () ;
bundlelist.add(list);
bundle.putParcelableArrayList("list",bundlelist);
intent.putExtras(bundle); オブジェクトを Json 文字列に変換するか、シリアル化するかの 2 種類があります。 Serializable と Parcelable を通じて Android の組み込み Json パーサーの使用は推奨されません。fastjson または Gson サードパーティ ライブラリを使用できます。
1) オブジェクトを Json 文字列に変換します
public class Author{
private int id;/...
}
public class Author{ private int id; private String name;
//...}
Book book=new Book();
book.setTitle ("Java プログラミング思考");
著者 author=new Author();
author.setId(1);
author.setName("Bruce Eckel");
book.setAuthor(author);
Intenttent=new Intent (this,SecondActivity .class);
intent.putExtra("book",new Gson().toJson(book));
读取数据:
Book book=new Gson().fromJson(bookJson,Book.class);
Log.d(TAG,"本のタイトル->"+book.getTitle());
Log.d(TAG,"本の著者名->"+book.getAuthor().getName());
2) Serializable, Parcelable を使用してオブジェクトをシリアル化する
1. シリアル化可能な実装:
① ビジネス Bean の実装: シリアル化可能なインターフェイス、getter メソッドと setter メソッドを記述する
② インテント呼び出し putExtra(String name, Serializable value) を渡すオブジェクトインスタンス もちろん、複数のオブジェクトがある場合は、最初に Bundle.putSerializable(x,x); することもできます
③新しいアクティビティは getSerializableExtra() メソッドを呼び出してオブジェクト インスタンスを取得します。 例:Product pd = (Product) getIntent().getSerializableExtra("Product");
④オブジェクトの get メソッドを呼び出して、対応するパラメータを取得します
2. Parcelable 実装:
一般的なプロセス:
① ビジネス Bean は Parcelable インターフェイスを継承し、writeToParcel メソッドをオーバーライドし、オブジェクトを Parcel オブジェクトにシリアル化します。② descriptionContents メソッド、コンテンツ インターフェイスの説明を書き換え、デフォルトで 0 を返します。
③ 静的内部オブジェクト CREATOR をインスタンス化します。 Creator
インターフェースParcelableを実装します。④同様に、IntentのputExtra()メソッドを通じてオブジェクトのインスタンスを渡します。 それをバンドル Bundle.putParcelable(x,x) に入れてから、Intent.putExtras()
いくつかの説明:
writeToParcel を通じてオブジェクトを Parcel オブジェクトにマップし、次に createFromParcel を通じて Parcel オブジェクトをマップします。 あなたのオブジェクトになります。 Parcel をストリームとみなして、writeToParcel を通じてオブジェクトをストリームに書き込むこともできます。 createFromParcel を通じてストリームからオブジェクトを読み取りますが、このプロセスでは実装する必要があるため、次のように記述します。 順序と読み取り順序は一貫している必要があります。
Parcelable インターフェイスを実装するコード例:
@Override
public int describeContents() {
return 0; を管理する必要はありません。
}
@Override
public void writeToParcel(Parcel parcel, int flags){
parcel.writeString(bookName);
parcel.writeString(作成者);
parcel.writeInt(publishTime);
}
public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {
@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();
mBook を返す;
}
};
Android Studio は Parcleable プラグインを生成します:
Intellij/Andriod Studio プラグイン android-parcelable-intellij-plugin ALT+Insert を押すだけで、Parcleable インターフェイス コードを直接生成できます。
さらに: Parcable オブジェクトは Android で広く使用されており、Parcable インターフェイスの実装は非常に面倒です。 サードパーティのオープンソース フレームワーク: Parceler、Maven に問題があるため、まだ試していません。
参考アドレス:[AndroidのParcelableが自動生成]
3. 2つのシリアル化方法の比較:
2つの比較:
- 1) メモリを使用する場合、ParcelableはSerializable Highよりも優れたパフォーマンスを発揮します。 Parcelable を使用することをお勧めします。
- 2) Serializable はシリアル化中に大量の一時変数を生成し、頻繁な GC を引き起こします。
- 3) Parcelable はデータの整合性を保証できないため、データをディスクに保存する場合は使用できません。 外界の変化に直面しても継続すること。 Serializable は効率が劣りますが、現時点では Serializable を使用することをお勧めします。
5. Intent は Bitmap を渡します
bitmap はデフォルトで Parcelable インターフェースを実装しており、直接渡すことができます
実装コード:
Intenttent = new Intent();
Bundleバンドル = 新しいバンドル();
bundle.putParcelable("ビットマップ", ビットマップ);
intent.putExtra("バンドル", バンドル);
6. グローバルデータを直接渡すのは不便です
そのような要求がある場合は、アクティビティ 1 -> アクティビティ 2 -> アクティビティ 4、 Activity 内の特定のデータを Activity4 に渡したいのですが、それをページ間で渡すにはどうすればよいですか?
明らかに非科学的ですよね? 特定のデータをどこでも利用できるようにしたい場合は、Application グローバル オブジェクト の使用を検討できます。
Android システムは、各プログラムの実行時に Application オブジェクトを作成しますが、作成されるのは 1 つだけなので、Application シングルトンパターンのクラスであり、Application オブジェクトのライフサイクルはプログラム全体の中で最も長くなります。 期間はこのプログラムのライフサイクルと同じです。より静的な値(固定および変更も可能)を保存したい場合、使用したい場合 アプリケーションには、Application クラスを実装し、インスタンス化されたカスタム アプリケーションであることをシステムに伝えるためのカスタム クラスが必要です。 このステップでは、システムのデフォルトではなく、AndroidManifest.xml のアプリケーション タグに name 属性 を追加します。
コードの重要な部分:
1) カスタムアプリケーションクラス:
private String myState;
public String getState(){
return myState;
}
public void setState (String s){
myState = s;
}
}
2) AndroidManifest.xml のステートメント:
android:label="@string/app_name">
3) 必要に応じて呼び出します:
@Override
public void onCreate(Bundle b){
.. .
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}
高精細な書き込み方法
: Application グローバル オブジェクトは任意の場所で取得できます。アプリケーションはシステムのコンポーネントであり、独自のライフサイクルもあり、これはonCraeteで取得できます アプリケーションオブジェクト。改造コードを投稿してください! Class myApp拡張アプリケーション{
プライベートストリングミステート;public void onCreate(){
onCreate();
インスタンス = this;
その後、どこでも MyApp.getInstance() を直接呼び出して、アプリケーションのグローバル オブジェクトを取得できます。
注:
Application オブジェクトはメモリ内に存在し、次のシナリオのようにシステムによって強制終了される可能性があります:
Activity1 のアプリケーションにユーザー アカウントを保存し、次に、Activity1 でユーザー アカウントを取得します。 Activity2を表示してみよう!
ホームボタンをクリックし、N 時間待機した後、システムはメモリを再利用するためにアプリを強制終了します。このとき、私たちは再び、 このアプリを開くと、この時点で魔法のようにアクティビティ 2 ページに戻りますが、この時点でアプリケーションを再度取得すると、 ユーザーアカウントが入力されると、プログラムは NullPointerException を報告してクラッシュします~
上記のクラッシュが発生する理由は、Application オブジェクトが新しく作成されたためであると考えられるかもしれません。 実際にはそうではなく、新しいアプリケーションを作成し、ユーザーが最後に終了したときにアクティビティを開始して、アプリケーションを作成するだけです。 殺されるという幻想はない!したがって、より重要なデータの場合は、データを使用する際にさらにローカライズすることをお勧めします。 変数の値が null でないことを確認する必要があります。もう 1 つのポイントは、これはアプリケーション変数だけでなく、シングルトン オブジェクトやパブリック静的変数にも当てはまります。 このようになります~
7. シングルトンモードのパラメータの受け渡し
上記のアプリケーションはシングルトンに基づいています。シングルトンモードの特徴は、システム内のクラスが 1 つだけのインスタンスを持つことを保証できることです。 これは非常に簡単に実現でき、A でパラメータを設定し、B で直接アクセスします。これは、いくつかの方法の中で最も効率的です。
サンプルコード: (コードはインターネットから来ます~)
①単一ケースクラスを定義します:
インスタンス = new String, Object>
}
}
public void put(String key,Object value){
~
}
}
②パラメータを設定します:
XclSingleton.getInstance().put("key1", "value1");
XclSingleton.getInstance().put("key2", "value2" ; パラメータを渡すにはアプリケーション パターンとシングルトン パターンを使用してください。データ移行で皆さんに便利になると思います、ありがとうございます~