如何从 AsyncTask 获取并显示一个值?
How to get and show a value from an AsyncTask?
我想获取并显示通过 Asynctask 获得的值,但我对它不是很熟悉...
我的异步任务:
private class loadDetails extends AsyncTask<Void,Void,Void>() {
@Override
protected void doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
//?
}
}
我的完整 activity 代码:
public class MovieDetailActivity extends AppCompatActivity {
private ImageView backdrop_image, poster;
private TextView overview, releaseDate, genresList;
private RatingBar rating;
private static final String TAG = "MovieDetails";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_movie_detail);
new loadDetails().execute();
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(details.getTitle());
backdrop_image = findViewById(R.id.movie_backdrop_image);
poster = findViewById(R.id.movie_poster);
title = findViewById(R.id.movie_title);
releaseDate = findViewById(R.id.movie_release_date);
rating = (RatingBar) findViewById(R.id.movie_rating_bar);
overview = findViewById(R.id.movie_overview);
genresList = findViewById(R.id.movie_genres);
if (details != null){
Glide.with(this)
.load(IMAGE_BASE_URL + details.getBackdropPath())
.apply(RequestOptions.placeholderOf(R.color.colorPrimary))
.into(backdrop_image);
Glide.with(this)
.load(IMAGE_BASE_URL + details.getPosterPath())
.apply(RequestOptions.placeholderOf(R.color.colorPrimary))
.into(poster);
title.setText(details.getTitle());
releaseDate.setText(details.getReleaseDate());
overview.setText(details.getOverview());
double d = details.getTMDBRating();
float f = (float) d;
rating.setRating(f/2);
}
}
private class loadDetails extends AsyncTask<Void,Void,Void>() {
@Override
protected void doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
//?
}
}
@Override
public boolean onSupportNavigateUp(){
finish();
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.save_menu, menu);
return true;
}
}
我想在 TextView 中显示 runtime
。
您可以尝试以下方法:
//create a method to set the value to the textview
private void setTextViewValue(int runtime)
{
textView.setText(String.valueOf(runtime))
}
//change the last parameter to Integer
private class loadDetails extends AsyncTask<Void,Void,Integer>() {
@Override
protected Integer doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return runtime;
}
@Override
protected void onPostExecute(Integer runtime) {
//call the method to set the runtime value
setTextViewValue(runtime);
}
}
简单说明一下AsyncTask的参数如下:
第一个参数 - 传递给 execute() 函数并由 doInBackground() 接收的值的数据类型
第二个参数 - 传递给 onProgressUpdate() 的值的数据类型
第三个参数是 doInBackground 返回的值的数据类型,并在调用时传递给 onPostExecute()
OnPostExecute 随后将调用您的自定义函数以将文本设置为 textview。
private class loadDetails extends AsyncTask<Void,Void,Integer>() {
@Override
protected Integer doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return runtime;
}
@Override
protected void onPostExecute(Integer anInt) {
yourTextView.setText("yourInt = " + anInt);
}
}
应该可以解决问题。我没有编译它,但通常异步任务的第三个泛型参数是 return 类型,从 doInBackround()
到 onPostExecute()
并且那里你可以触摸你的观点。
AsyncTask 不了解生命周期,这意味着如果用户更改配置,您的应用程序将泄漏内存;它甚至可能崩溃。因此,您需要使用 Livedata and ViewModel,它只会在 activity 处于活动状态时更新您的 activity。如果您的应用程序崩溃,您将失去客户,这在业界被认为是糟糕的编程习惯。
我想获取并显示通过 Asynctask 获得的值,但我对它不是很熟悉...
我的异步任务:
private class loadDetails extends AsyncTask<Void,Void,Void>() {
@Override
protected void doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
//?
}
}
我的完整 activity 代码:
public class MovieDetailActivity extends AppCompatActivity {
private ImageView backdrop_image, poster;
private TextView overview, releaseDate, genresList;
private RatingBar rating;
private static final String TAG = "MovieDetails";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_movie_detail);
new loadDetails().execute();
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(details.getTitle());
backdrop_image = findViewById(R.id.movie_backdrop_image);
poster = findViewById(R.id.movie_poster);
title = findViewById(R.id.movie_title);
releaseDate = findViewById(R.id.movie_release_date);
rating = (RatingBar) findViewById(R.id.movie_rating_bar);
overview = findViewById(R.id.movie_overview);
genresList = findViewById(R.id.movie_genres);
if (details != null){
Glide.with(this)
.load(IMAGE_BASE_URL + details.getBackdropPath())
.apply(RequestOptions.placeholderOf(R.color.colorPrimary))
.into(backdrop_image);
Glide.with(this)
.load(IMAGE_BASE_URL + details.getPosterPath())
.apply(RequestOptions.placeholderOf(R.color.colorPrimary))
.into(poster);
title.setText(details.getTitle());
releaseDate.setText(details.getReleaseDate());
overview.setText(details.getOverview());
double d = details.getTMDBRating();
float f = (float) d;
rating.setRating(f/2);
}
}
private class loadDetails extends AsyncTask<Void,Void,Void>() {
@Override
protected void doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
//?
}
}
@Override
public boolean onSupportNavigateUp(){
finish();
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.save_menu, menu);
return true;
}
}
我想在 TextView 中显示 runtime
。
您可以尝试以下方法:
//create a method to set the value to the textview
private void setTextViewValue(int runtime)
{
textView.setText(String.valueOf(runtime))
}
//change the last parameter to Integer
private class loadDetails extends AsyncTask<Void,Void,Integer>() {
@Override
protected Integer doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return runtime;
}
@Override
protected void onPostExecute(Integer runtime) {
//call the method to set the runtime value
setTextViewValue(runtime);
}
}
简单说明一下AsyncTask的参数如下:
第一个参数 - 传递给 execute() 函数并由 doInBackground() 接收的值的数据类型
第二个参数 - 传递给 onProgressUpdate() 的值的数据类型
第三个参数是 doInBackground 返回的值的数据类型,并在调用时传递给 onPostExecute()
OnPostExecute 随后将调用您的自定义函数以将文本设置为 textview。
private class loadDetails extends AsyncTask<Void,Void,Integer>() {
@Override
protected Integer doInBackground(Void... voids) {
final Movie details = (Movie) getIntent().getExtras().getSerializable("MOVIE_DETAILS");
int idMovie = details.getId();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.themoviedb.org/3/movie/" + idMovie + "?api_key=" + API_KEY + "&language=en-US")
.build();
Response response = client.newCall(request).execute();
JSONObject root = new JSONObject(response.body().string());
int runtime = root.getInt("runtime");
Log.i("test", runtime + " min");
return runtime;
}
@Override
protected void onPostExecute(Integer anInt) {
yourTextView.setText("yourInt = " + anInt);
}
}
应该可以解决问题。我没有编译它,但通常异步任务的第三个泛型参数是 return 类型,从 doInBackround()
到 onPostExecute()
并且那里你可以触摸你的观点。
AsyncTask 不了解生命周期,这意味着如果用户更改配置,您的应用程序将泄漏内存;它甚至可能崩溃。因此,您需要使用 Livedata and ViewModel,它只会在 activity 处于活动状态时更新您的 activity。如果您的应用程序崩溃,您将失去客户,这在业界被认为是糟糕的编程习惯。