В следующем простом примере кода есть асинхронная задача, которая несколько раз спит в течение 2 секунд, а затем запускает функцию обратного вызова onResultAvailable
с "some text .."
(которую я здесь использую для имитации потока веб-сокетов, получающего сообщения ...).
Метод onResultAvailable
в классе MyViewModel
должен обновлять переменную text
(которая является MutableLiveData<String>
), используя postValue
(потому что он вызывается из фонового потока).
Таким образом, этот код должен обновлять переменную text
каждые две секунды и отображать текст через наблюдателя в MyTestActivity
;поэтому предполагается, что в первый раз будет работать следующее:
Some text 0
Some text 1
Some text 2
... etc
Однако, когда я нажимаю кнопку и затем снова открываю MyTestActivity
, переменная text
не изменяетсябольше на postvalue
и наблюдатель больше не вызывается.Обратите внимание, что другие переменные, которые модифицируются с помощью setvalue
, по-прежнему ведут себя как ожидалось.
Любые идеи, почему postvalue
отлично работает в фоновом потоке в первый раз, но больше не работает, когда активностьуничтожили потом воссоздали?Как я могу обновить значение переменной text
в этом случае?
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.myButton);
button.setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, MyTestActivity.class));
});
}
}
MyTestActivity.java
public class MyTestActivity extends AppCompatActivity {
TextView myTextView, myTextViewTime;
Button myButton;
MyViewModel vm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_test);
myTextView = findViewById(R.id.myTextView);
myTextViewTime = findViewById(R.id.myTextViewTime);
myButton = findViewById(R.id.myButton);
vm = ViewModelProviders.of(this).get(MyViewModel.class);
vm.getText().observe(this, text -> {
myTextView.setText(text);
Log.d("DEBUG", "observed: " + text);
});
vm.getTimestamp().observe(this, strTs -> {
myTextViewTime.setText(strTs);
Log.d("DEBUG", "observed: " + strTs);
});
myButton.setOnClickListener(v -> {
vm.setTimestamp("" + System.currentTimeMillis());
});
}
}
MyViewModel.java
public class MyViewModel extends ViewModel implements MyAsyncTaskDelegate {
private MutableLiveData<String> text;
private MutableLiveData<String> timestamp;
private MyAsyncTask task;
public MyViewModel() {
text = new MutableLiveData<>();
text.setValue("Hello World!");
timestamp = new MutableLiveData<>();
timestamp.setValue(""+System.currentTimeMillis());
task = new MyAsyncTask(this);
task.execute();
}
public LiveData<String> getText() {
return text;
}
public LiveData<String> getTimestamp() {
return timestamp;
}
public void setTimestamp(String ts) {
timestamp.setValue(ts);
}
@Override
public void onResultAvailable(String result) {
text.postValue(result);
}
}
MyAsyncTask.java
public class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private MyAsyncTaskDelegate delegate;
MyAsyncTask(MyAsyncTaskDelegate delegate) {
this.delegate = delegate;
}
@Override
protected Void doInBackground(Void... voids) {
for(int i = 0; i < 100; i++) {
try {
Thread.sleep(2000);
delegate.onResultAvailable("Some text " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
}
MyAsyncTaskDelegate.Ява
public interface MyAsyncTaskDelegate {
void onResultAvailable(String result);
}