私が持っているList
と呼ばれるmessages
私のActivity.Inでプロパティをsynchronization()
、私はと呼ばれるgetDateMessage(upadated_at)
この関数値function.Inをmessages
変更しましたが、にプログラム行くときsynchronization
messages
リストは空です。
private List<message_model> messages = new ArrayList<>();
private void synchronization() {
getDateMessage(upadated_at);
Log.e("MSDF",messages.toString()+" list tostring");
}
private void getDateMessage(String date) {
MessengerActivity.APIInterface apiInterface = app_net.getRetrofitInstance().create(MessengerActivity.APIInterface.class);
retrofit2.Call<List<message_model>> call = apiInterface.getMessageDate(Ptoken, date);
call.enqueue(new Callback<List<message_model>>() {
@Override
public void onResponse(Call<List<message_model>> call, Response<List<message_model>> response) {
if(response.isSuccessful()) {
messages.addAll(response.body());
Log.e("MSDF",response.body().toString()+" responsebody in call");
Log.e("MSDF",messages.toString()+" message in call");
Log.e("MESSAGE", "getDateMessage successful");
}
}
@Override
public void onFailure(Call<List<message_model>> call, Throwable t) {
Log.e("MESSAGE", "getDateMessage" + t.toString());
}
});
}
そして、これは私のlogcatです。
09-30 14:34:53.714 10763-10763/idea.mahdi.bime E/MSDF: [] list tostring
09-30 14:34:54.104 10763-10763/idea.mahdi.bime E/MSDF: [message_model{id=33, thread_id=2, user_id=15, body='چطوری', created_at='2018-09-29 10:28:26', updated_at='2018-09-29 10:28:26', deleted_at='null'}, message_model{id=30, thread_id=2, user_id=15, body='سلام', created_at='2018-09-29 09:30:40', updated_at='2018-09-29 09:30:40', deleted_at='null'}, message_model{id=7, thread_id=2, user_id=15, body='hi', created_at='2018-09-24 09:55:46', updated_at='2018-09-24 09:55:46', deleted_at='null'}] responsebody in api
09-30 14:34:54.104 10763-10763/idea.mahdi.bime E/MSDF: [message_model{id=33, thread_id=2, user_id=15, body='چطوری', created_at='2018-09-29 10:28:26', updated_at='2018-09-29 10:28:26', deleted_at='null'}, message_model{id=30, thread_id=2, user_id=15, body='سلام', created_at='2018-09-29 09:30:40', updated_at='2018-09-29 09:30:40', deleted_at='null'}, message_model{id=7, thread_id=2, user_id=15, body='hi', created_at='2018-09-24 09:55:46', updated_at='2018-09-24 09:55:46', deleted_at='null'}] message in api
09-30 14:34:54.104 10763-10763/idea.mahdi.bime
E/MESSAGE: getDateMessage successful
問題は、あなたがgetDataMessage()を呼び出すと、それは非同期呼び出し(後付けエンキュー()メソッド)を実行することです。アンドロイドアプリケーションはメインスレッドに維持する一方、サーバーは、backgroudのスレッドでメッセージを取得するために呼び出されます。
そのため、Log.e("MSDF",messages.toString()+" list tostring");
改造呼び出しが行われる前に、したがって、まだ利用可能な現在のデータがないと呼ばれています。あなたはそれがロード完了した後、あなたがデータで何かをやっていることを確認してください。
private List<message_model> messages = new ArrayList<>();
private void synchronization() {
getDateMessage(upadated_at);
// Anything you put here will be called before the data (messages) is loaded.
// Do not work with your messages here, they'll be null.
}
private void getDateMessage(String date) {
MessengerActivity.APIInterface apiInterface = app_net.getRetrofitInstance().create(MessengerActivity.APIInterface.class);
retrofit2.Call<List<message_model>> call = apiInterface.getMessageDate(Ptoken, date);
call.enqueue(new Callback<List<message_model>>() {
@Override
public void onResponse(Call<List<message_model>> call, Response<List<message_model>> response) {
if(response.isSuccessful()) {
messages.addAll(response.body());
Log.e("MSDF",response.body().toString()+" responsebody in call");
Log.e("MSDF",messages.toString()+" message in call");
Log.e("MESSAGE", "getDateMessage successful");
// Anything you want to do with the messages should be placed here. When you are sure the data is completed.
Log.e("MSDF",messages.toString()+" list tostring");
}
}
@Override
public void onFailure(Call<List<message_model>> call, Throwable t) {
Log.e("MESSAGE", "getDateMessage" + t.toString());
}
});
}
それはチェックする価値がif (response.body() != null)
NPEを避けるためにそれで何かを行う前に。
EDIT
それはコメントで頼まれたとおり。良い解決策は、(Googleがそれをお勧めします)に記載されるようにビューモデルを使用してデータをフェッチすることで、このアンドロイドデベロッパーガイド物品。
ViewModelにアプローチが良いです理由は次のとおりです。
- データは、(あなたのデバイスを回転させる場合など、メッセージのリストは、あなたのアプリにはまだなります)構成の変更時に持続します。
- これは、メモリリークが発生することはありません。
- あなたは、UIコントローラロジックからビューデータの所有権を分けます。
あなたは記事の他の利点を見ることができます。
ファイル: - 1あなたのbuild.gradle(アプリモジュール)でビューモデルの依存性を追加します。
dependencies {
def lifecycle_version = "1.1.1"
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
}
参照してくださいここに最新バージョンを。
2 - のViewModelクラスを作成します。
MessageViewModel.java
public class MessagesViewModel extends ViewModel {
private MutableLiveData<List<message_model>> messagesList;
public LiveData<List<message_model>> getMessages() {
if (messagesList == null) {
messagesList = new MutableLiveData<List<message_model>>();
loadMessages();
}
return messagesList;
}
private void loadMessages() {
MessengerActivity.APIInterface apiInterface = app_net.getRetrofitInstance().create(MessengerActivity.APIInterface.class);
retrofit2.Call<List<message_model>> call = apiInterface.getMessageDate(Ptoken, date);
call.enqueue(new Callback<List<message_model>>() {
@Override
public void onResponse(Call<List<message_model>> call, Response<List<message_model>> response) {
if(response.isSuccessful()) {
if (response.body() != null) {
messagesList.setValue(response.body());
}
}
}
@Override
public void onFailure(Call<List<message_model>> call, Throwable t) {
// Handle failure
}
});
}
}
3 - あなたの活動でメッセージを取得します
public class MainActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
MessagesViewModel model = ViewModelProviders.of(this).get(MessagesViewModel.class);
model.getMessages().observe(this, messagesList -> {
// Do whatever you want with the list of messages.
});
}
}
あなたの活動は今どのようにきれいに見えます。
次に、あなたが実装することができSwipeRefreshLayoutを使用すると、ユーザーがデータを更新できるようにする場合。
それが十分でない場合は、このチェックできReposViewModelを
改造を呼び出すと、一般に公開されようとしているのアプリのメインのコアであれば最後に、あなたはで説明したように、ダガー2及びRxJavaを使用してMVVMのアプローチを導入する必要があり、この記事。(これは高度です)