[英]How do I observe a result from FutureTask in ViewModel?
请帮忙~我想在 ViewModel 中观察 FutureTask 的结果。 当我运行它时,我发现它休眠了 5 秒,但我仍然无法得到答案。 我在调试模式下确认它正在执行 longJob(),答案是 3。但我仍然无法得到答案 3。答案总是 [No answer]。
我的代码如下
MainActivity.java
// MainActivity.java
package com.weberhwang.testlivedata;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.weberhwang.testlivedata.databinding.ActivityMainBinding;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private MyViewModel myViewModel;
private TextView result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
result = binding.result;
result.setText("No answer");
SummaryLiveData summaryLiveData = new SummaryLiveData();
summaryLiveData.setB(2);
SummaryCallable summaryCallable = new SummaryCallable();
summaryCallable.setSummaryLiveData(summaryLiveData);
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
myViewModel.setSummaryCallable(summaryCallable);
try {
myViewModel.getAnswer().observe(this, new Observer<SummaryLiveData>() {
@Override
public void onChanged(SummaryLiveData s) {
result.setText(String.valueOf(s.getAnswer()));
}
});
} catch (Exception e) {
Log.d("MyLog", e.getMessage());
}
}
}
MyViewModel.java
MyViewMode.java
package com.weberhwang.testlivedata;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import java.util.concurrent.FutureTask;
public class MyViewModel extends AndroidViewModel {
private SummaryCallable summaryCallable;
public MyViewModel(@NonNull Application application) {
super(application);
}
public SummaryLiveData getAnswer() throws Exception {
FutureTask<Object> task = new FutureTask<>(summaryCallable);
new Thread(task).start();
return (SummaryLiveData) task.get();
}
public void setSummaryCallable(SummaryCallable summaryCallable) {
this.summaryCallable = summaryCallable;
}
}
摘要Callable.java
// SummaryCallable.java
package com.weberhwang.testlivedata;
import androidx.lifecycle.LiveData;
import java.util.concurrent.Callable;
public class SummaryCallable implements Callable<Object> {
private SummaryLiveData summaryLiveData;
@Override
public Object call() throws Exception {
summaryLiveData.longJob();
return summaryLiveData;
}
public void setSummaryLiveData(SummaryLiveData summaryLiveData) {
this.summaryLiveData = summaryLiveData;
}
}
摘要LiveData.java
// SummaryLiveData.java
package com.weberhwang.testlivedata;
import androidx.lifecycle.LiveData;
public class SummaryLiveData extends LiveData {
private int a = 1;
private int b = 0;
private int answer = 0;
public void longJob() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
answer = a + b;
}
public void setB(int b) {
this.b = b;
}
public int getAnswer() {
return answer;
}
}
activity_main.xml
// activity_main.xml
package com.weberhwang.testlivedata;
import androidx.lifecycle.LiveData;
public class SummaryLiveData extends LiveData {
private int a = 1;
private int b = 0;
private int answer = 0;
public void longJob() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
answer = a + b;
}
public void setB(int b) {
this.b = b;
}
public int getAnswer() {
return answer;
}
}
我将我的程序固定如下。 然后就是工作了。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/result" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package com.weberhwang.testmutablelivedata;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.weberhwang.testmutablelivedata.databinding.ActivityMainBinding;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private MyViewModel myViewModel;
private TextView result;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
result = binding.result;
button = binding.button;
result.setText("No answer");
Summary summary = new Summary();
summary.setB(2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
summary.setB(3);
try {
myViewModel.getAnswer(summary);
} catch (Exception e) {
e.printStackTrace();
}
}
});
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
try {
myViewModel.getAnswer(summary).observe(this, new Observer<Summary>() {
@Override
public void onChanged(Summary s) {
result.setText(String.valueOf(s.getAnswer()));
}
});
} catch (Exception e) {
Log.d("MyLog", e.getMessage());
}
}
}
MyViewModel.java
package com.weberhwang.testmutablelivedata;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;
import java.util.concurrent.FutureTask;
public class MyViewModel extends AndroidViewModel {
private MutableLiveData<Summary> summaryMutableLiveData = new MutableLiveData<>();
public MyViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<Summary> getAnswer(Summary summary) throws Exception {
SummaryCallable summaryCallable = new SummaryCallable();
summaryCallable.setSummary(summary);
FutureTask<Object> task = new FutureTask<>(summaryCallable);
new Thread(task).start();
summaryMutableLiveData.setValue((Summary) task.get());
return summaryMutableLiveData;
}
}
摘要.java
package com.weberhwang.testmutablelivedata;
public class Summary {
private int a = 1;
private int b = 0;
private int answer = 0;
public void longJob() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
answer = a + b;
}
public void setB(int b) {
this.b = b;
}
public int getAnswer() {
return answer;
}
}
摘要Callable.java
package com.weberhwang.testmutablelivedata;
import java.util.concurrent.Callable;
public class SummaryCallable implements Callable<Object> {
private Summary summary;
@Override
public Object call() throws Exception {
summary.longJob();
return summary;
}
public void setSummary(Summary summary) {
this.summary = summary;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.