I am making an app that fetches json data by making http requests and after parsing that data it populate the views in layout and also store that json data in string in a list data collection . In layout there is an image view that is filled with Picasso finally I have two fragments in ViewPager .And each fragment has pagination to load more data and they fill result list by getting json data for each page.
I also have to
Store coming http json response to list and for both fragments
Recycler View Adapters for both fragments in heap.
While loading more list data have faced following fetal error.
Process: mashhood.meshsoft.com.gn_news, PID: 18465
java.lang.OutOfMemoryError: Failed to allocate a 94784012 byte allocation with 4194304 free bytes and 87MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:655)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:483)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1157)
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:720)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:571)
at android.content.res.Resources.loadDrawable(Resources.java:972)
at android.content.res.TypedArray.getDrawable(TypedArray.java:931)
at android.widget.ImageView.<init>(ImageView.java:157)
at android.widget.ImageView.<init>(ImageView.java:145)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:60)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:56)
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:106)
at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1029)
at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1087)
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:47)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:769)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at mashhood.meshsoft.com.gn_news.movies.Adapters.RecyclerViewAdapters.RecyclerViewForMoiveDiscovery.onCreateViewHolder(RecyclerViewForMoiveDiscovery.java:74)
at mashhood.meshsoft.com.gn_news.movies.Adapters.RecyclerViewAdapters.RecyclerViewForMoiveDiscovery.onCreateViewHolder(RecyclerViewForMoiveDiscovery.java:39)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6367)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5555)
at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:282)
at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:336)
at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:349)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:356)
at android.support.v7.widget.GapWorker.run(GapWorker.java:387)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
While adapter for RecyclerView is as follows
/**
* Created by Mashhood on 3/14/2018.
*/
public class RecyclerViewForMoiveDiscovery extends RecyclerView.Adapter<RecyclerViewForMoiveDiscovery.MyViewHolder> {
//this is for the class fields
public Context ctx;
public List<DiscoverMovies> list; //this is for the list of items
//end of the class fields as it should be
//this is for the holder for the thread reasoning
public Handler handler; //this is for the handler to handle ui thread
//end of the holder for the thread reasoning
//this is for the constructor
public RecyclerViewForMoiveDiscovery(Context context,List<DiscoverMovies>list){
this.ctx=context; //this is for context
this.list=list; //this is for the list
//this is for the initialization of handler
handler=new Handler(); //this is for the handler
//end of initialization for handler
}
//end of the constructor
//this is for the RecyclerView Methods
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//this is for the LayoutInFlator
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.movie_item,parent,false);
//end of the LayoutInFlator
//this is to create the view holder
MyViewHolder myViewHolder=new MyViewHolder(view);
//end of view holder
return myViewHolder; //this is for myViewHolder
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
try{
final DiscoverMovies discoverMovies=list.get(holder.getAdapterPosition()); //this is for getting current object
//now to place it in views
holder.movie_rating.setText(discoverMovies.getVoteAverage()); //this is for average vote
holder.movie_name.setText(discoverMovies.getTitle()); //this is for the movie name
holder.movie_year.setText(discoverMovies.getRelease_date()); //this is for the release date
holder.overview_text.setText(discoverMovies.getOverview()); //this is for the overview for movies
//end of the placement
try{
//this is for the picasso work to get the image
Picasso.with(this.ctx).load(discoverMovies.getPoster_path()).error(R.drawable.moive_item_background).into(holder.picture);
//end of the picasso work to get the image
}
catch (Exception ex){
LogPrinting("Exception of type "+ex.getMessage()+"while loading the Image");
}//end of loading the Picture
//this is for the click listener for the watch trailer button
holder.watch_trailer_button.setOnClickListener(new View.OnClickListener() {
public final String movie_id=discoverMovies.getId(); //this is for getting the movie id
@Override
public void onClick(View v) {
if(isOnline()){
FindVideoIdForThatMovie(movie_id); //this is for finding the movie trailer
} //this is for the if
else{
ToastPrinting("Please get Internet Connection");
}//end of else
}
});
//end of the block for the click listener for the watch trailer button
//this is for the holder watch movie button
holder.watch_movie_button.setOnClickListener(new View.OnClickListener() {
public final String movie_id=discoverMovies.getId(); //this is for the movie id
@Override
public void onClick(View v) {
try{
if(isOnline())
{
Intent i=new Intent(ctx, MoviePlayer.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this is for the new task
Bundle b=new Bundle();
b.putString("id",movie_id);
i.putExtras(b);
ctx.startActivity(i);
}
else{
ToastPrinting("Please get a Internet Connection");
}
} //end of the try
catch (Exception ex){
LogPrinting("Exception of type is as follows "+ex.getMessage());
}//end of the catch
}
});
//end of watch movie button
}//end of the try
catch(Exception ex){
LogPrinting("Exception while binding the Values with view items "+ex.getMessage());
}//end of catch
} // end of the OnBindViewHolder
@Override
public int getItemCount() {
return list.size(); //this is for the list Size
}
//end of RecyclerView Methods
//this is for the Log and Toast printing
private static final String TAG = "RecyclerViewForMoiveDis";
public void LogPrinting(String Line){
Log.d(TAG,Line); //this is for the Log Printing
}//this is for Log
public void ToastPrinting(String Line){
Toast.makeText(this.ctx,Line,Toast.LENGTH_SHORT).show();
}//end of Toast
//end of Log And Toast Printing
//this is for the ViewHolder
class MyViewHolder extends RecyclerView.ViewHolder{
//this is for the class fields
public View view; //this is for the view
// this is for the public view
public TextView movie_rating; //this is for the movie_rating
public TextView movie_name; //this is for the movie name
public TextView movie_year; //this is for the movie year
public TextView overview_text; //this is for the movie overview
public Button watch_trailer_button ; //this is for the trailer
public Button watch_movie_button; //this is to watch movie
public ImageView picture; //this is for the picture
//end of the public view
//end of view items
public MyViewHolder(View itemView) {
super(itemView);
view=itemView;
InitializeComponents(); //this is to initialize the components
}
//end of the class fields
//this is for the initialization of the components
public void InitializeComponents(){
try{
movie_rating=(TextView) view.findViewById(R.id.movie_rating); //this is for rating
movie_name=(TextView) view.findViewById(R.id.movie_name); //this is for the movie name
movie_year=(TextView) view.findViewById(R.id.movie_year); //this is for the movie year
overview_text=(TextView) view.findViewById(R.id.overview_text); //this is for overview text
watch_trailer_button=(Button) view.findViewById(R.id.watch_trailer_button); //this is for watch trailer button
watch_movie_button=(Button) view.findViewById(R.id.watch_movie_button); //watch movie button
picture=(ImageView) view.findViewById(R.id.movie_picture); //this is for the movie picture
}//end of the try
catch (Exception ex){
LogPrinting("Exception of type is as follows "+ex.getMessage());
}//end of catch
}
//end of the initialization of the components
}
//end of the ViewHolder
//this is for loading the video id for a given movie
public void FindVideoIdForThatMovie(final String movieId){
try{
//there we will make the http request for that page
Thread t=new Thread(new Runnable() {
@Override
public void run() {
//inner try catch
try{
URL url=new URL(new UrlData().GiveMeUrlForVideo(movieId)); //this is for the url
URLConnection urlConnection=url.openConnection(); //this is to open http connection
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); //this is for the buffered reader
String Line=""; //this is for the Line
String temporary_line=""; //this is for the temporary line
//this is for the loop to get the data
while((temporary_line=bufferedReader.readLine())!=null){ //keep on reading the Line till no line
Line +=temporary_line; //this is for the temporary Line
} //end of the loop to get the data
//to print what we have got
LogPrinting("Coming Video data is as \n"+Line); //this is for the Line
//end of printing what we have got
//this is for the parsing phase
try{
JSONObject mainJSONObject=new JSONObject(Line); //this is for main JSONObject
JSONArray jsonArray=mainJSONObject.getJSONArray("results"); //this is for getting the json array
JSONObject very_first_object=(JSONObject) jsonArray.get(0); //this is for json array
final String youtube_video_id= very_first_object.get("key").toString(); //this is for the youtube video id
//now we have to code for sending that video id to new youtube activity
handler.post(new Runnable() {
@Override
public void run() {
try{
Intent i=new Intent(ctx, YouTubePlayerActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //this is for the new task
Bundle b=new Bundle();
b.putString("id",youtube_video_id);
i.putExtras(b);
ctx.startActivity(i);
}//end of try
catch (Exception ex3){
LogPrinting("Exception while opening the youtube activity "+ex3.getMessage());
}
}
});
//end of the activity for sending that video id to new youtube activity
}//end of try block
catch (Exception exi){
LogPrinting("Exception of type "+exi.getMessage()+" while parsing the json data for videos");
}
//end of the parsing phase
}//end of try
catch (Exception ex){
LogPrinting("Exception of type "+ex.getMessage()+" while loading the videos data for that job ");
}
//end of inner try catch
}
}); //end of Thread
t.start();
//end of making the http request for that page
}//end of the try block
catch (Exception ex){
LogPrinting("Exception of type "+ex.getMessage()+" while loading the video id from source in Recycler Adapter for Movies");
}//end of the catch block for loading the movies from movies sources
}
//end of loading the video id for a given movie
//this is for checking either the user is online
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) this.ctx.getSystemService(ctx.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
//end of checking either user is online or not
}//end of the class