如何在管理堆时克服 OutOfMemoryError?
How to overcome OutOfMemoryError while managing heap?
我正在制作一个应用程序,它通过发出 http 请求来获取 json 数据,并在解析该数据后填充布局中的视图,并且 还将 json 数据存储在字符串中在列表数据集合 中。在布局中,有一个充满 Picasso 的图像视图,最后我在 ViewPager 中有两个片段 。每个片段都有分页以加载更多数据,它们通过以下方式填充结果列表获取每个页面的 json 数据。
我也要
存储即将到来的 http json 对列表和两个片段的响应
堆中两个片段的回收器视图适配器。
加载更多列表数据时遇到以下错误。
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)
而RecyclerView的适配器如下
/**
* 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
OutOfMemoryError 当 dalvik VM 拒绝允许分配更多内存时发生 resources.As 在所讨论的问题中,正在使用名为 RecyclerViewForMoiveDiscovery 的 RecyclerViewAdapter 中的 Picasso 从远程主机加载大量图像。即使在完成 activity 之后, 位图 仍保留在内存中,导致大量内存使用,直到导致 OutOfMemoryError。在研究了类似类型的不同案例后,我知道我们可以在使用 Picasso 时选择跟随。
我们应该设置一个stableKey同时设置url到picasso来获取图像
Picasso.with(上下文).load(image_url).stableKey(stable_key).into(holder.picture);
和在Activity销毁我们必须通过给出stableKey来使该文件无效,如下
Picasso.with(context).invalidate(stable_key);
- 第二种方法是跳过内存缓存并将网络策略设置为
NetworkPolicy.NO_CACHE
这样做我使用以下代码Picasso.with(context).load(path).skipMemoryCache().networkPolicy(NetworkPolicy.NO_CACHE).error(R.drawable.default_image).into(imageView);
这是防止缓存的更好方法但是 毕加索开始 [=23=] 需要更多时间来加载 图像。
- 第三种方法是请求 VM 为资源提供更多动态内存,为此我们通过在应用程序 tag.This 下的清单中写入
android:largeHeap="true"
来发出请求,这是一种更简单的方法,但不好,因为如果我们这样做可能会导致内存 leak.Effective 方法是通过使用 Runtime.getRuntime.gc()
. 使内存从动态分配的对象中释放出来来管理堆
我正在制作一个应用程序,它通过发出 http 请求来获取 json 数据,并在解析该数据后填充布局中的视图,并且 还将 json 数据存储在字符串中在列表数据集合 中。在布局中,有一个充满 Picasso 的图像视图,最后我在 ViewPager 中有两个片段
我也要
存储即将到来的 http json 对列表和两个片段的响应
堆中两个片段的回收器视图适配器。
加载更多列表数据时遇到以下错误。
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)
而RecyclerView的适配器如下
/**
* 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
OutOfMemoryError 当 dalvik VM 拒绝允许分配更多内存时发生 resources.As 在所讨论的问题中,正在使用名为 RecyclerViewForMoiveDiscovery 的 RecyclerViewAdapter 中的 Picasso 从远程主机加载大量图像。即使在完成 activity 之后, 位图 仍保留在内存中,导致大量内存使用,直到导致 OutOfMemoryError。在研究了类似类型的不同案例后,我知道我们可以在使用 Picasso 时选择跟随。
我们应该设置一个stableKey同时设置url到picasso来获取图像
Picasso.with(上下文).load(image_url).stableKey(stable_key).into(holder.picture);
和在Activity销毁我们必须通过给出stableKey来使该文件无效,如下
Picasso.with(context).invalidate(stable_key);
- 第二种方法是跳过内存缓存并将网络策略设置为
NetworkPolicy.NO_CACHE
这样做我使用以下代码Picasso.with(context).load(path).skipMemoryCache().networkPolicy(NetworkPolicy.NO_CACHE).error(R.drawable.default_image).into(imageView);
这是防止缓存的更好方法但是 毕加索开始 [=23=] 需要更多时间来加载 图像。 - 第三种方法是请求 VM 为资源提供更多动态内存,为此我们通过在应用程序 tag.This 下的清单中写入
android:largeHeap="true"
来发出请求,这是一种更简单的方法,但不好,因为如果我们这样做可能会导致内存 leak.Effective 方法是通过使用Runtime.getRuntime.gc()
. 使内存从动态分配的对象中释放出来来管理堆