将字符串从AsyncTask传递到onCreate或其他活动

时间:2018-07-26 09:08:12

标签: android

我正在尝试使用AsyncTask在后台线程上查询JSON数据,并在同一Activity的onCreate中使用查询中的值之一。我应该怎么做?我应该使用意图还是有更直观,更好的方法?

在下面的代码中,我试图使用AsyncTask从在线数据库中提取youtube ID。之所以有效,是因为当我在AsyncTask中记录值时,会显示正确的youtube ID。但是我需要在onCreate中使用此ID,以便可以使用它创建完整的youtube URL。如何将YouTube ID字符串从doInBackground传递给onCreate?该ID存储在变量youtubeId

 //Activity needs added to manifest.
public class DetailsActivity extends AppCompatActivity {

    //LOG tag for debugging
    private static final String TAG = "GalleryActivity";

    String youtubeIdCode;

    //Override on Create and set contentView to new activity_details layout.
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_details);
        //Log for debugging so we can tell if activity started successfully.
        Log.d(TAG, "onCreate: started.");

        loadMovieData();

        Intent intent = getIntent();
        Movie movie = intent.getParcelableExtra("movie");

        String image = movie.getMoviePoster();
        String title = movie.getTitle();
        String releaseDate = movie.getDate();
        String voteAverage = movie.getVoteAverage();
        String plot = movie.getPlot();

        ImageView poster = findViewById(R.id.details_image);
        Picasso.with(this).load(image).into(poster);

        TextView name = findViewById(R.id.details_title);
        name.setText((getResources().getString(R.string.movie_title)) + " " + title);

        TextView dateRelease = findViewById(R.id.details_release_date);
        dateRelease.setText((getResources().getString(R.string.release_date)) + " " + releaseDate);

        TextView averageVote = findViewById(R.id.details_voter_average);
        averageVote.setText((getResources().getString(R.string.vote_average)) + " " + voteAverage);

        TextView moviePlot = findViewById(R.id.details_plot);
        moviePlot.setText((getResources().getString(R.string.plot)) + " " + plot);

        ImageView watchTrailer = findViewById(R.id.imageView);

//        watchTrailer.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(trailerUrl.toString()));
//                Log.v("OnClick URL",trailerUrl.toString());
//                startActivity(intent);
//            }
//        });

    }

    public class FetchTrailer extends AsyncTask<String, Void, Void> {

        @Override
        protected Void doInBackground(String... strings) {
            final String YOUTUBE_ID = "id";
            final String RESULTS = "results";
            String youtubeId = " ";

            Intent intent = getIntent();
            Movie movie = intent.getParcelableExtra("movie");
            String id = movie.getID();

            final URL trailerUrl = NetworkUtils.buildUrlTrailer(id);
            Log.v("Built trailer url", trailerUrl.toString());

            try {
                String jsonResponse = NetworkUtils.getReponseFromHttpUrl(trailerUrl);

                JSONObject moviesObject = new JSONObject(jsonResponse);

                JSONArray resultsArray = moviesObject.getJSONArray(RESULTS);

                for(int i = 0; i < resultsArray.length(); i ++){
                    JSONObject movieObject = resultsArray.getJSONObject(i);
                    youtubeId = movieObject.getString(YOUTUBE_ID);
                    Log.v("youtubeid", youtubeId);
                }

            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

    //Tell the new method to get the data based on the search term within the url.
    private void loadMovieData() {
        //If there is a network connection, fetch the data.
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null &&
                activeNetwork.isConnectedOrConnecting();
        if (isConnected) {
            new FetchTrailer().execute();
        } else {
            Toast toast = Toast.makeText(this, getString(R.string.no_internet_toast), Toast.LENGTH_LONG);
            toast.show();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

似乎youtubeId是DetailsActivity的先决条件。因此,在DetailsActivity初始化之前,我们需要youtubeId。

在您之前的活动中,可以从该用户登陆到DetailsActivity,然后调用 startActivity(intent)呼叫

  

loadMovieData()

方法保持不变,您必须在先前的活动中声明方法。之后,通过意图将youtubeId传递给DetailsActivity,然后您可以在oncreate()中检索值:

Intent myIntent = new Intent(CurrentActivity.this, 
NextActivity.class);
myIntent.putExtra("youtubeId", value); //Optional parameters
CurrentActivity.this.startActivity(myIntent);

其他方面则通过以下方式获取:

@Override
protected void onCreate(Bundle savedInstanceState) {
 Intent intent = getIntent();
 String value = intent.getStringExtra("youtubeId"); //if it's a string you 
 stored.
}

答案 1 :(得分:0)

您可以使用回调侦听器来实现此目的

public interface FetchTrailerListener {
   public void onTrailerFetched(String youtubeId);
}

使DetailsActivity得以实现。实例化时,将此侦听器引用传递给asynctask。这样,从postexecute中通过该侦听器通知活动。

protected void onPostExecute( String youtubeId) {
   fetchTrailerListenr.onTrailerFetched(youtubeId);
}