Issue
Kindly suggest me a fix for the problem:
I am unable to figure out why onProgressUpdate and onPostExecute from AsyncTask class are not getting called after execution of doInBackground or onPreExecute.
This is my Fragment class rendering Youtube Playlists where I would like to implement ProgressBar.
public class YouTubeRecyclerViewFragment extends Fragment {
// the fragment initialization parameter
private static final String ARG_YOUTUBE_PLAYLIST_IDS = "YOUTUBE_PLAYLIST_IDS";
private String[] mPlaylistIds;
private ArrayList<String> mPlaylistTitles;
//private RecyclerView mRecyclerView;
private RecyclerViewPager mRecyclerView;
private PlaylistVideos mPlaylistVideos;
private RecyclerView.LayoutManager mLayoutManager;
private PlaylistCardAdapter mPlaylistCardAdapter;
private YouTube mYouTubeDataApi;
public static YouTubeRecyclerViewFragment newInstance(YouTube youTubeDataApi, String[] playlistIds) {
YouTubeRecyclerViewFragment fragment = new YouTubeRecyclerViewFragment();
Bundle args = new Bundle();
args.putStringArray(ARG_YOUTUBE_PLAYLIST_IDS, playlistIds);
fragment.setArguments(args);
fragment.setYouTubeDataApi(youTubeDataApi);
return fragment;
}
public YouTubeRecyclerViewFragment() {
// Required empty public constructor
}
public void setYouTubeDataApi(YouTube api) {
mYouTubeDataApi = api;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
if (getArguments() != null) {
mPlaylistIds = getArguments().getStringArray(ARG_YOUTUBE_PLAYLIST_IDS);
}
// start fetching the playlist titles
new GetPlaylistTitlesAsyncTask(mYouTubeDataApi) {
@Override
protected void onPostExecute(PlaylistListResponse playlistListResponse) {
// if we didn't receive a response for the playlist titles, then there's nothing to update
if (playlistListResponse == null)
return;
mPlaylistTitles = new ArrayList();
for (com.google.api.services.youtube.model.Playlist playlist : playlistListResponse.getItems()) {
mPlaylistTitles.add(playlist.getSnippet().getTitle());
}
}
}.execute(mPlaylistIds);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// set the Picasso debug indicator only for debug builds
Picasso.with(getActivity()).setIndicatorsEnabled(BuildConfig.DEBUG);
// Inflate the layout for this fragment
//View rootView = inflater.inflate(R.layout.youtube_recycler_view_fragment, container, false);
View rootView = inflater.inflate(R.layout.youtube_recycler_view_fragment, container, false);
//mRecyclerView = (RecyclerView) rootView.findViewById(R.id.youtube_recycler_view);
mRecyclerView = (RecyclerViewPager) rootView.findViewById(R.id.youtube_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
Resources resources = getResources();
if (resources.getBoolean(R.bool.isTablet)) {
// use a staggered grid layout if we're on a large screen device
mLayoutManager = new StaggeredGridLayoutManager(resources.getInteger(R.integer.columns), StaggeredGridLayoutManager.VERTICAL);
} else {
// use a linear layout on phone devices
//mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager = new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false);
}
mRecyclerView.setLayoutManager(mLayoutManager);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// if we have a playlist in our retained fragment, use it to populate the UI
if (mPlaylistVideos != null) {
// reload the UI with the existing playlist. No need to fetch it again
reloadUi(mPlaylistVideos, false);
} else {
// otherwise create an empty playlist using the first item in the playlist id's array
mPlaylistVideos = new PlaylistVideos(mPlaylistIds[0]);
// and reload the UI with the selected playlist and kick off fetching the playlist content
reloadUi(mPlaylistVideos, true);
}
}
private void reloadUi(final PlaylistVideos playlistVideos, boolean fetchPlaylist) {
// initialize the cards adapter
initCardAdapter(playlistVideos);
if (fetchPlaylist) {
// start fetching the selected playlistVideos contents
new GetPlaylistAsyncTask(mYouTubeDataApi,getContext()) {
@Override
public void onPostExecute(Pair<String, List<Video>> result) {
handleGetPlaylistResult(playlistVideos, result);
}
}.execute(playlistVideos.playlistId, playlistVideos.getNextPageToken());
}
}
private void initCardAdapter(final PlaylistVideos playlistVideos) {
// create the adapter with our playlistVideos and a callback to handle when we reached the last item
mPlaylistCardAdapter = new PlaylistCardAdapter(playlistVideos, new LastItemReachedListener() {
@Override
public void onLastItem(int position, String nextPageToken) {
new GetPlaylistAsyncTask(mYouTubeDataApi,getContext()) {
@Override
public void onPostExecute(Pair<String, List<Video>> result) {
handleGetPlaylistResult(playlistVideos, result);
}
}.execute(playlistVideos.playlistId, playlistVideos.getNextPageToken());
}
});
mRecyclerView.setAdapter(mPlaylistCardAdapter);
}
private void handleGetPlaylistResult(PlaylistVideos playlistVideos, Pair<String, List<Video>> result) {
if (result == null) return;
final int positionStart = playlistVideos.size();
playlistVideos.setNextPageToken(result.first);
playlistVideos.addAll(result.second);
mPlaylistCardAdapter.notifyItemRangeInserted(positionStart, result.second.size());
}
/**
* Interface used by the {@link PlaylistCardAdapter} to inform us that we reached the last item in the list.
*/
public interface LastItemReachedListener {
void onLastItem(int position, String nextPageToken);
}
}
Below is the AsyncTask class that is used to fetch videos from the playlist supplied:
public abstract class GetPlaylistAsyncTask extends AsyncTask<String, Void, Pair<String, List<Video>>> {
private static final String TAG = "GetPlaylistAsyncTask";
private static final Long YOUTUBE_PLAYLIST_MAX_RESULTS = 10L;
//see: https://developers.google.com/youtube/v3/docs/playlistItems/list
private static final String YOUTUBE_PLAYLIST_PART = "snippet";
private static final String YOUTUBE_PLAYLIST_FIELDS = "pageInfo,nextPageToken,items(id,snippet(resourceId/videoId))";
//see: https://developers.google.com/youtube/v3/docs/videos/list
private static final String YOUTUBE_VIDEOS_PART = "snippet,contentDetails,statistics"; // video resource properties that the response will include.
private static final String YOUTUBE_VIDEOS_FIELDS = "items(id,snippet(title,description,thumbnails/high),contentDetails/duration,statistics)"; // selector specifying which fields to include in a partial response.
private YouTube mYouTubeDataApi;
Context mContext;
ProgressDialog progressBar;
public GetPlaylistAsyncTask(YouTube api, Context context) {
mYouTubeDataApi = api;
mContext = context;
progressBar = new ProgressDialog(mContext);
}
@Override
protected Pair<String, List<Video>> doInBackground(String... params) {
final String playlistId = params[0];
final String nextPageToken;
if (params.length == 2) {
nextPageToken = params[1];
} else {
nextPageToken = null;
}
PlaylistItemListResponse playlistItemListResponse;
try {
playlistItemListResponse = mYouTubeDataApi.playlistItems()
.list(YOUTUBE_PLAYLIST_PART)
.setPlaylistId(playlistId)
.setPageToken(nextPageToken)
.setFields(YOUTUBE_PLAYLIST_FIELDS)
.setMaxResults(YOUTUBE_PLAYLIST_MAX_RESULTS)
.setKey(ApiKey.YOUTUBE_API_KEY)
.execute();
} catch (IOException e) {
e.printStackTrace();
return null;
}
if (playlistItemListResponse == null) {
Log.e(TAG, "Failed to get playlist");
return null;
}
List<String> videoIds = new ArrayList();
// pull out the video id's from the playlist page
for (PlaylistItem item : playlistItemListResponse.getItems()) {
videoIds.add(item.getSnippet().getResourceId().getVideoId());
}
// get details of the videos on this playlist page
VideoListResponse videoListResponse = null;
try {
videoListResponse = mYouTubeDataApi.videos()
.list(YOUTUBE_VIDEOS_PART)
.setFields(YOUTUBE_VIDEOS_FIELDS)
.setKey(ApiKey.YOUTUBE_API_KEY)
.setId(TextUtils.join(",", videoIds)).execute();
} catch (IOException e) {
e.printStackTrace();
}
return new Pair(playlistItemListResponse.getNextPageToken(), videoListResponse.getItems());
}
@Override
protected void onPreExecute() {
progressBar = new ProgressDialog(mContext);
progressBar.setCancelable(true);
progressBar.setMessage("Processing Request");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setIndeterminate(true);
progressBar.show();
}
@Override
protected void onProgressUpdate(Void... values) {
progressBar.setMessage("I have found :");
}
@Override
protected void onPostExecute(Pair<String, List<Video>> stringListPair) {
progressBar.dismiss();
}
}
Solution
You need to use listener interface, handle onPostExecute
function like here:
How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
and change the code snippet
new GetPlaylistAsyncTask(mYouTubeDataApi,getContext()) {
@Override
public void onPostExecute(Pair<String, List<Video>> result) {
handleGetPlaylistResult(playlistVideos, result);
}
}.execute(playlistVideos.playlistId, playlistVideos.getNextPageToken());
as
new GetPlaylistAsyncTask(mYouTubeDataApi,getContext(),YouTubeRecyclerViewFragment.this)
.execute(playlistVideos.playlistId, playlistVideos.getNextPageToken());
@Override
public void handleGetPlaylistResult(PlaylistVideos playlistVideos, Pair<String, List<Video>> result) {
if (result == null) return;
if (playlistVideos == null){
playlistVideos = mPlaylistVideos;
}
final int positionStart = playlistVideos.size();
playlistVideos.setNextPageToken(result.first);
playlistVideos.addAll(result.second);
mPlaylistCardAdapter.notifyItemRangeInserted(positionStart, result.second.size());
}
GetPlaylistAsyncTask.java
public class GetPlaylistAsyncTask{
private AsyncResponse theListener;
public GetPlaylistAsyncTask(YouTube api, Context context, YouTubeRecyclerViewFragment frag ) {
mYouTubeDataApi = api;
mContext = context;
theListener = (AsyncResponse)frag;
}
@Override
public void onPostExecute(Pair<String, List<Video>> result) {
progressBar.dismiss();
theListener.handleGetPlaylistResult(null,result);
}
}
Answered By - misman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.