Как получить и показать значение из AsyncTask? - PullRequest
0 голосов
/ 04 июня 2019

Я хочу получить и показать значение, полученное с помощью 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) {
            //?
        }
    }

Мой полный код активности:

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;
    }
}

Я хочу отобразить runtime в TextView.

Ответы [ 3 ]

0 голосов
/ 04 июня 2019
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);
    }
}

это должно сработать .. Я не скомпилировал его, но обычно 3-й универсальный параметр асинхронной задачи - это тип возвращаемого значения от doInBackround() до onPostExecute(), и вы можете коснуться ваших представлений.

0 голосов
/ 04 июня 2019

AsyncTask не поддерживает жизненный цикл, это означает, что если пользователь изменит конфигурацию, ваше приложение утечет память; это может даже разбиться. Таким образом, вам нужно использовать Livedata и ViewModel , которые будут обновлять вашу активность только тогда, когда она активна. В случае сбоя вашего приложения вы потеряете клиентов, и это считается плохой практикой программирования в отрасли.

0 голосов
/ 04 июня 2019

Вы можете попробовать следующее:

//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 следующие:

  • 1-й параметр - тип данных значения, переданного функции execute () и полученной функцией doInBackground ()

  • 2-й параметр - тип данных значения, передаваемого в onProgressUpdate ()

  • 3-й параметр - это тип данных значения, возвращаемого doInBackground и передаваемого в onPostExecute () при его вызове

Затем OnPostExecute вызовет вашу пользовательскую функцию, чтобы установить текст в textview.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...