java.lang.OutOfMemoryError: বিটম্যাপ আকার ভিএম বাজেটের চেয়ে বেশি - অ্যান্ড্রয়েড


159

আমি একটি অ্যাপ্লিকেশন তৈরি করেছি যা অ্যান্ড্রয়েডে প্রচুর চিত্র ব্যবহার করে।

অ্যাপ্লিকেশন, একবার রান পর্দা (চালু তথ্য পূরণ Layouts, Listviews, Textviews, ImageViews, ইত্যাদি) এবং ব্যবহারকারীর তথ্য পড়া হয়।

কোনও অ্যানিমেশন নেই, কোনও বিশেষ প্রভাব বা স্মৃতি পূরণ করতে পারে এমন কোনও কিছুই নেই। কখনও কখনও অঙ্কনযোগ্য পরিবর্তন করতে পারে। কিছু অ্যান্ড্রয়েড সংস্থান এবং কিছু এসডিকার্ডের একটি ফোল্ডারে সংরক্ষিত ফাইল files

তারপরে ব্যবহারকারীটি প্রস্থান করে ( onDestroyপদ্ধতিটি কার্যকর হয়ে যায় এবং অ্যাপটি ভিএম দ্বারা স্মৃতিতে থাকে) এবং তারপরে কোনও একসময় ব্যবহারকারী আবার প্রবেশ করে।

প্রতিবার ব্যবহারকারী অ্যাপ্লিকেশনটিতে প্রবেশ করার পরে, ব্যবহারকারীটি না পাওয়া পর্যন্ত আমি মেমরিটিকে আরও এবং আরও বাড়তে দেখছি java.lang.OutOfMemoryError

তাহলে অনেকগুলি চিত্র পরিচালনা করার সেরা / সঠিক উপায় কী?

এগুলি কি স্থির পদ্ধতিতে রেখে দেওয়া উচিত যাতে তারা সর্বদা লোড হয় না? আমাকে কী বিশেষ বিন্যাসে লেআউটটিতে ব্যবহৃত লেআউট বা চিত্রগুলি পরিষ্কার করতে হবে?


4
আপনার যদি প্রচুর অঙ্কনযোগ্য পরিবর্তন করতে পারে তবে এটি সহায়তা করতে পারে। এটা তোলে কাজ করছে যেহেতু আমি প্রোগ্রাম নিজেকে :) করেনি androidactivity.wordpress.com/2011/09/24/...

উত্তর:


72

মনে হচ্ছে আপনার একটি স্মৃতি ফাঁস হয়েছে। সমস্যাটি অনেকগুলি চিত্র পরিচালনা করছে না, আপনার ক্রিয়াকলাপটি ধ্বংস হয়ে গেলে আপনার চিত্রগুলি হ্রাস পাচ্ছে না।

আপনার কোডটি না দেখে এটি কেন বলা শক্ত। তবে এই নিবন্ধটিতে কিছু টিপস রয়েছে যা সাহায্য করতে পারে:

http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html

বিশেষত, স্ট্যাটিক ভেরিয়েবলগুলি ব্যবহার করে জিনিসগুলি আরও খারাপ হতে পারে, আরও ভাল নয়। আপনার অ্যাপ্লিকেশনটি পুনরায় আঁকলে আপনাকে কলব্যাকগুলি সরিয়ে এমন কোড যুক্ত করতে পারে - তবে আবার, নিশ্চিতভাবে বলতে এখানে যথেষ্ট তথ্য নেই।


8
এটি সত্য এবং এছাড়াও প্রচুর চিত্র (এবং মেমরি ফাঁস নয়) এর ফলে অনেকগুলি অন্যান্য অ্যাপ্লিকেশন চলমান, মেমরির খণ্ডিতকরণ ইত্যাদির মতো অফ স্মৃতি বেরিয়ে আসতে পারে I পদ্ধতিগতভাবে, সর্বদা একই কাজ করার মতো, তারপরে এটি ফুটো। যদি আপনি এটি একবারে বা কোনও কিছুর মতো পান তবে এটি সীমাবদ্ধতার কাছাকাছি থাকার কারণে। এই ক্ষেত্রে আমার পরামর্শটি হ'ল কিছু জিনিস সরানোর চেষ্টা করুন এবং আবার চেষ্টা করুন। এছাড়াও চিত্রের স্মৃতি হিপ মেমরির বাইরে রয়েছে, সুতরাং উভয়ের সন্ধান করুন।
ড্যানিয়েল বেনিডিক্ট

15
আপনার যদি মেমরি ফুটো সন্দেহ হয় তবে হিপ ব্যবহারের নিরীক্ষণের একটি দ্রুত উপায় হ'ল অ্যাডবি শেল ডাম্পস মেমিনফো কমান্ডের মাধ্যমে। আপনি যদি কয়েকটি জিসি চক্রের (গিসি_ * লগকটে লগ সারিতে) গাদা ব্যবহার বাড়তে দেখেন তবে নিশ্চিত হতে পারেন যে আপনার ফুটো আছে। তারপরে অ্যাডিবি বা ডিডিএমএসের মাধ্যমে একটি হিপ ডাম্প (বা বিভিন্ন সময়ে বেশ কয়েকটি) তৈরি করুন এবং এ্যাক্লিপস এমএটি-তে ডমিনেটর ট্রি টুলিংয়ের মাধ্যমে বিশ্লেষণ করুন। আপনার খুব শীঘ্রই খুঁজে পাওয়া উচিত যে কোন বস্তুর একটি সময় ধরে বাড়তে থাকে তার ধরে রাখার হিপ রয়েছে। এটাই তোমার স্মৃতি ফুটো। আমি এখানে আরও কিছু বিশদ সহ একটি নিবন্ধ লিখেছি: macgyverdev.blogspot.com/2011/11/…
জোহান নরন

98

অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলি বিকাশ করে এমন একটি সাধারণ ত্রুটিটি হ'ল "java.lang.OutOfMemoryError: বিটম্যাপ আকার ভিএম বাজেটের ছাড়িয়ে গেছে" ত্রুটি। ওরিয়েন্টেশন পরিবর্তনের পরে প্রচুর বিটম্যাপ ব্যবহার করে ক্রিয়াকলাপগুলিতে আমি এই ত্রুটিটি ঘন ঘন পেয়েছি: ক্রিয়াকলাপটি ধ্বংস হয়ে গেছে, আবার তৈরি করা হয়েছে এবং বিএমটি ম্যাপের জন্য উপলব্ধ ভিএম মেমরি গ্রাসকারী এক্সএমএল থেকে লেআউটগুলি "ফুলে উঠেছে"।

পূর্ববর্তী ক্রিয়াকলাপের বিন্যাসে বিটম্যাপগুলি সঠিকভাবে আবর্জনা সংগ্রহকারী দ্বারা বরাদ্দ করা হয়নি কারণ তারা তাদের ক্রিয়াকলাপের রেফারেন্সগুলি অতিক্রম করেছে। অনেক পরীক্ষার পরে আমি এই সমস্যার জন্য বেশ ভাল সমাধান খুঁজে পেয়েছি।

প্রথমে আপনার এক্সএমএল লেআউটের প্যারেন্ট ভিউতে "আইডি" বৈশিষ্ট্যটি সেট করুন:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:id="@+id/RootView"
     >
     ...

তারপরে, onDestroy() আপনার ক্রিয়াকলাপের unbindDrawables()পদ্ধতিতে, পিতামাতার ভিউতে একটি রেফারেন্স পাস করার পদ্ধতিটিকে কল করুন এবং তারপরে একটি করুন System.gc()

    @Override
    protected void onDestroy() {
    super.onDestroy();

    unbindDrawables(findViewById(R.id.RootView));
    System.gc();
    }

    private void unbindDrawables(View view) {
        if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
        ((ViewGroup) view).removeAllViews();
        }
    }

এই unbindDrawables()পদ্ধতিটি পুনরাবৃত্তভাবে ভিউ ট্রিটিকে অন্বেষণ করে এবং:

  1. সমস্ত পটভূমি ড্রইবলগুলিতে কলব্যাকগুলি সরিয়ে দেয়
  2. প্রতিটি ভিউ গ্রুপে থাকা বাচ্চাদের সরিয়ে দেয়

10
Java.lang.UnsupportedOperationException ছাড়া: অ্যাডাপ্টারভিউ-এ সরানো সমস্ত ভিউস () সমর্থিত নয়

ধন্যবাদ এটি আমার গাদা আকারকে উল্লেখযোগ্যভাবে হ্রাস করতে সাহায্য করে যেহেতু আমার কাছে প্রচুর অঙ্কনযোগ্য ables
এরিক চেন

5
বা কেবল শর্তটি পরিবর্তন করুন: যদি (ভিউগ্রুপ &&& উদাহরণস্বরূপ দেখুন (অ্যাডাপ্টারভিউ দেখুন))
আনেকে

2
@ অ্যাডাম ভারহেগেই, আপনি স্পষ্টভাবে অনডেস্ট্রয় গ্যালারী দেখার জন্য একই ফাংশন কল করতে পারেন। আনবাইন্ডড্রেইবলগুলি (গ্যালারীভিউ) এর মতো; আশা করি এটি আপনার জন্য কাজ করে ...
এইচপি.অ্যান্ড্রয়েড

1
এই দুটি gotcha এ জন্য সতর্ক stackoverflow.com/questions/8405475/... এবং stackoverflow.com/questions/4486034/...
max4ever

11

এই সমস্যা এড়ানোর জন্য আপনি নেটিভ পদ্ধতি ব্যবহার করতে পারেন Bitmap.recycle()আগে null-ing Bitmapবস্তু (বা অন্য মূল্য জন্য উপলব্ধ সেটিং)। উদাহরণ:

public final void setMyBitmap(Bitmap bitmap) {
  if (this.myBitmap != null) {
    this.myBitmap.recycle();
  }
  this.myBitmap = bitmap;
}

এবং এরপরে আপনি myBitmapডাব্লু / ও কলিং এর System.gc()মতো পরিবর্তন করতে পারেন:

setMyBitmap(null);    
setMyBitmap(anotherBitmap);

1
যদি তালিকা উপাদানগুলিতে এই উপাদানগুলি যুক্ত করার চেষ্টা করা হয় তবে এটি কাজ করবে না। সে বিষয়ে আপনার কোনও পরামর্শ আছে?
রাফেল সান্চে

@ddmytrenko আপনি চিত্রটি অর্পণ করার আগে পুনর্ব্যবহার করছেন। এটি কি এর পিক্সেলগুলি রেন্ডারিং থেকে আটকাবে না?
ইগোরগানাপলস্কি

8

আমি এই সঠিক সমস্যার মধ্যে দৌড়ে এসেছি। গাদাটি খুব ছোট তাই এই চিত্রগুলি মেমরির ক্ষেত্রে দ্রুত নিয়ন্ত্রণের বাইরে চলে যেতে পারে। একটি উপায় হ'ল আবর্জনা সংগ্রহকারীকে তার পুনর্ব্যবহারের পদ্ধতিটি কল করে বিটম্যাপে মেমরি সংগ্রহ করার ইঙ্গিত দেওয়া ।

এছাড়াও, অনডস্ট্রয় পদ্ধতিতে কল করার নিশ্চয়তা নেই। আপনি এই যুক্তিটি সরিয়ে / অনপেজ ক্রিয়াকলাপে পরিষ্কার করতে চাইতে পারেন। আরও তথ্যের জন্য এই পৃষ্ঠায় ক্রিয়াকলাপ জীবনচক্র ডায়াগ্রাম / টেবিলটি দেখুন।


তথ্যের জন্য ধন্যবাদ। আমি বিটম্যাপস না করে সমস্ত ড্রয়াবল পরিচালনা করছি, তাই আমি রিসাইক্লাকে কল করতে পারি না। অঙ্কনযোগ্যদের জন্য অন্য কোনও পরামর্শ? ড্যানিয়েল ধন্যবাদ
ড্যানিয়েল বেনিডিক্ট

onPauseপরামর্শের জন্য ধন্যবাদ । আমি Bitmapসেগুলির মধ্যে সমস্ত চিত্র সহ 4 টি ট্যাব ব্যবহার করছি , সুতরাং ক্রিয়াকলাপ ধ্বংস করা খুব শীঘ্রই ঘটতে পারে না (যদি ব্যবহারকারী সমস্ত ট্যাব ব্রাউজ করেন)।
আজুরস্পট

7

এই ব্যাখ্যাটি সহায়তা করতে পারে: http://code.google.com/p/android/issues/detail?id=8488#c80

"দ্রুত পরামর্শ:

1) কখনও নিজেকে কল করুন System.gc ()। এটি এখানে স্থির হিসাবে প্রচার করা হয়েছে, এবং এটি কার্যকর হয় না। এটি করবেন না. আপনি যদি আমার ব্যাখ্যাটিতে লক্ষ্য করে থাকেন, আউটআফমিউরিওর পাওয়ার আগে, জেভিএম ইতিমধ্যে একটি আবর্জনা সংগ্রহ চালায় যাতে এটি করার আর কোনও কারণ নেই (এটি আপনার প্রোগ্রামটি ধীর করে দিচ্ছে)। আপনার ক্রিয়াকলাপ শেষে একটি কাজ করা কেবল সমস্যাটি coveringেকে রাখে। এটি বিটম্যাপটিকে দ্রুত চূড়ান্তকরণের কাতারে রাখার কারণ হতে পারে, তবে এর পরিবর্তে প্রতিটি বিটম্যাপে আপনি কেবল রিসাইক্ল বলতে পারেননি এমন কোনও কারণ নেই।

2) আপনার আর প্রয়োজন হয় না এমন বিটম্যাপে সর্বদা রিসাইকেল () কল করুন। খুব কমপক্ষে, আপনার ক্রিয়াকলাপের অনড্রেস্ট্রয়তে গিয়ে আপনি যে সমস্ত বিটম্যাপ ব্যবহার করছেন তা পুনরায় ব্যবহার করুন। এছাড়াও, আপনি যদি ডালভিক হিপ থেকে বিটম্যাপের উদাহরণগুলি দ্রুত সংগ্রহ করতে চান তবে বিটম্যাপের কোনও রেফারেন্স সাফ করাতে ক্ষতি হয় না।

3) রিসাইকালে কল () এবং তারপরে System.gc () এখনও ডালভিক হিপ থেকে বিটম্যাপটি সরিয়ে ফেলতে পারে না। এই সম্পর্কে চিন্তা করা করবেন না। পুনর্ব্যবহারযোগ্য () এর কাজটি করেছে এবং নেটিভ স্মৃতি মুক্ত করেছে, ডালভিকের গাদা থেকে বিটম্যাপটি সরিয়ে ফেলতে আমি আগে যে ধাপগুলি আগেই উল্লেখ করেছি তাতে যেতে কিছুটা সময় লাগবে। এটি কোনও বড় বিষয় নয় কারণ দেশীয় মেমরির বৃহত অংশ ইতিমধ্যে নিখরচায়!

4) সর্বদা ধরে নিন ফ্রেমওয়ার্কটিতে কোনও বাগ আছে। ডালভিক যা করার কথা ঠিক তা করছে। এটি আপনি যা প্রত্যাশা করেন বা কী চান তা নাও হতে পারে তবে এটি কীভাবে কার্যকর হয়। "


5

আমার ঠিক একই সমস্যা ছিল. কয়েকটি পরীক্ষার পরে আমি দেখতে পেলাম যে বৃহত চিত্র স্কেলিংয়ের জন্য এই ত্রুটিটি উপস্থিত হচ্ছে। আমি চিত্রের স্কেলিং হ্রাস করেছি এবং সমস্যাটি অদৃশ্য হয়ে গেছে।

পিএস প্রথমে আমি চিত্রটি নীচে স্কেল না করে চিত্রের আকার হ্রাস করার চেষ্টা করেছি। ত্রুটি থামেনি।


4
আপনি কীভাবে চিত্রের স্কেলিংটি করেছিলেন সেই কোডটি পোস্ট করতে পারেন, আমি একই সমস্যার মুখোমুখি হচ্ছি এবং আমি মনে করি এটি এটি সমাধান করতে পারে। ধন্যবাদ!
গ্লিগর

@ গিক্স - আমি বিশ্বাস করি যে তার অর্থ হল যে তিনি প্রকল্পের উত্সগুলিতে আনার আগে চিত্রগুলির আকার হ্রাস করতে হয়েছিল, এভাবে আঁকামুক্তদের স্মৃতিচিহ্নকে হ্রাস করতে হবে। এর জন্য আপনার নিজের পছন্দমতো ফটো এডিটর ব্যবহার করা উচিত। আমি পিক্স্লার ডট কম পছন্দ করি
কাইল ক্লেগ

5

নিম্নলিখিত বিষয়গুলি সত্যিই আমাকে অনেক সাহায্য করেছিল। অন্যান্য পয়েন্টগুলিও থাকতে পারে তবে এগুলি অত্যন্ত গুরুত্বপূর্ণ:

  1. যেখানে সম্ভব সেখানে অ্যাপ্লিকেশন প্রসঙ্গ (ক্রিয়াকটি.টির পরিবর্তে) ব্যবহার করুন।
  2. ক্রিয়াকলাপের (ਰੋਕ) পদ্ধতিতে আপনার থ্রেডগুলি থামান এবং ছেড়ে দিন
  3. OnDestroy () পদ্ধতিতে আপনার মতামত / কলব্যাকগুলি প্রকাশ করুন ks

4

আমি এই সমস্যাটি সমাধান করার জন্য একটি সুবিধাজনক উপায় প্রস্তাব করছি। আপনার ত্রুটিযুক্ত ক্রিয়াকলাপের জন্য মেইনফেষ্ট.এক্সএমএল অনুসারে কেবল "অ্যান্ড্রয়েড: কনফিগারেশনস" মানটি নির্ধারণ করুন। এটার মত:

<activity android:name=".main.MainActivity"
              android:label="mainActivity"
              android:configChanges="orientation|keyboardHidden|navigation">
</activity>

আমি যে প্রথম সমাধানটি দিয়েছিলাম তা OOM ত্রুটির ফ্রিকোয়েন্সিটিকে কম স্তরে ফেলেছে। কিন্তু, এটি সমস্যার সম্পূর্ণ সমাধান করেনি। এবং তারপরে আমি দ্বিতীয় সমাধানটি দেবো:

ওওএম বিস্তারিত হিসাবে, আমি খুব বেশি রানটাইম মেমরি ব্যবহার করেছি। সুতরাং, আমি আমার প্রকল্পের চিত্র / আকার / চিত্রের মধ্যে হ্রাস করব। যেমন একটি অতিমাত্রায়িত ছবি যার রেজোলিউশন 128X128 রয়েছে, এটি আবার x৪x৪৪64 আকারে পরিবর্তন করা যেতে পারে যা আমার আবেদনের জন্যও উপযুক্ত be এবং আমি ছবিগুলির একটি গাদা দিয়ে এটি করার পরে, OOM ত্রুটিটি আর ঘটে না।


1
এটি কাজ করে কারণ আপনি নিজের অ্যাপ্লিকেশনটি পুনরায় চালু করতে এড়াচ্ছেন। সুতরাং এটি এতটা সমাধান নয় কারণ এটি এড়ানো an তবে কখনও কখনও এটি আপনার প্রয়োজন হয়। এবং ক্রিয়াকলাপে কনফিগারেশন-চেঞ্জড () পদ্ধতিটি আপনার ক্রিয়াকলাপটি আপনার জন্য ঝাঁকিয়ে দেবে, সুতরাং যদি অন্যরকম অভিযোজনগুলির সাথে সত্যই খাপ খাইয়ে নিতে কোনও UI পরিবর্তনের প্রয়োজন না হয় তবে আপনি ফলাফলটি নিয়ে পুরোপুরি খুশি হতে পারেন। তবে আপনাকে পুনরায় আরম্ভ করতে পারে এমন অন্যান্য বিষয়গুলির জন্য সতর্ক থাকুন। আপনি এটি ব্যবহার করতে চাইতে পারেন: অ্যান্ড্রয়েড: কনফিগারেশন = "কীবোর্ডহিডান | ওরিয়েন্টেশন | কীবোর্ড | লোকেল | এমসিসি | এমসিএন | টাচস্ক্রিন | স্ক্রিনলয়আউট | ফন্টস্কেল"
কার্ল

3

আমিও বহির্মুখী বাগ দ্বারা হতাশ। এবং হ্যাঁ, আমিও দেখতে পেয়েছি যে চিত্রগুলি স্কেলিংয়ের সময় এই ত্রুটিটি অনেকটা পপ আপ হয়। প্রথমে আমি সমস্ত ঘনত্বের জন্য চিত্রের আকার তৈরি করার চেষ্টা করেছি, তবে আমি দেখতে পেয়েছি এটি আমার অ্যাপ্লিকেশনের আকারকে যথেষ্ট পরিমাণে বাড়িয়েছে। সুতরাং আমি এখন সমস্ত ঘনত্বের জন্য কেবল একটি চিত্র ব্যবহার করছি এবং আমার চিত্রগুলি স্কেলিং করছি।

যখনই ব্যবহারকারী এক ক্রিয়াকলাপ থেকে অন্য ক্রিয়াকলাপে যান তখন আমার অ্যাপ্লিকেশনটি একটি বহির্মুখী ত্রুটি ছুঁড়ে মারত। আমার অঙ্কনযোগ্যগুলিকে নালায় সেট করা এবং সিস্টেম.gc () কল করা কার্যকর হয়নি, আমার বিটম্যাপড্রেইবলগুলি গেটবিটম্যাপ () দিয়ে পুনর্ব্যবহার করতে পারেনি re অ্যান্ড্রয়েড প্রথম পদ্ধতির সাথে বহির্মুখী ত্রুটি ছুঁড়ে মারতে থাকবে, এবং যখনই এটি দ্বিতীয় পদ্ধতির সাথে পুনর্ব্যবহৃত বিটম্যাপ ব্যবহার করার চেষ্টা করবে তখন এটি ক্যানভাস ত্রুটি বার্তা নিক্ষেপ করবে।

আমি এমনকি একটি তৃতীয় পদ্ধতির গ্রহণ। আমি সমস্ত মতামত নালায় এবং পটভূমিটি কালো করে রেখেছি। আমি আমার অনটপ () পদ্ধতিতে এই ক্লিনআপটি করি। ক্রিয়াকলাপটি আর দৃশ্যমান না হওয়ার সাথে সাথে এটি হ'ল এমন পদ্ধতি। আপনি যদি অনপস () পদ্ধতিতে এটি করেন তবে ব্যবহারকারীরা একটি কালো পটভূমি দেখতে পাবেন। আদর্শ নয়। অনডেট্রয়ে () পদ্ধতিতে এটি করার জন্য, এটি কল হওয়ার কোনও গ্যারান্টি নেই।

ব্যবহারকারী যদি ডিভাইসে ব্যাক বোতামটি চাপ দেয় তবে একটি কালো পর্দা যাতে ঘটতে না পারে সেজন্য আমি স্টার্টঅ্যাক্টিভিটি (গেটইন্টেন্ট ()) কল করে ওপরেস্টার্ট () পদ্ধতিতে কার্যকলাপটি পুনরায় লোড করি এবং তারপরে () পদ্ধতিগুলি শেষ করি।

দ্রষ্টব্য: ব্যাকগ্রাউন্ডটি কালো করে তোলা সত্যিই প্রয়োজন হয় না।


1

বিটম্যাপফ্যাক্টরি.ডেকোড * পদ্ধতিগুলি, লোড লার্জ বিটম্যাপস দক্ষতার পাঠে আলোচিত , মূল ইউআই থ্রেডে চালিত করা উচিত নয় যদি উত্স ডেটাটি ডিস্ক বা কোনও নেটওয়ার্ক অবস্থান থেকে পড়া হয় (বা সত্যিকারের স্মৃতি ছাড়া অন্য কোনও উত্স)। এই ডেটাটি লোড হতে সময়টি অনুমানযোগ্য এবং বিভিন্ন কারণের উপর নির্ভর করে (ডিস্ক বা নেটওয়ার্ক থেকে পড়ার গতি, চিত্রের আকার, সিপিইউর শক্তি ইত্যাদি)। যদি এই কাজের মধ্যে কোনওটি ইউআই থ্রেডকে অবরুদ্ধ করে থাকে, সিস্টেমটি আপনার অ্যাপ্লিকেশনটিকে অ-প্রতিক্রিয়াশীল হিসাবে পতাকাঙ্কিত করবে এবং ব্যবহারকারীর এটি বন্ধ করার বিকল্প রয়েছে (আরও তথ্যের জন্য প্রতিক্রিয়াশীলতার জন্য ডিজাইনিং দেখুন)।


0

ওয়েল আমি ইন্টারনেটে যা কিছু পেয়েছি তা চেষ্টা করেছি এবং সেগুলির কোনওটিই কাজ করে নি। System.gc () কে কল করা কেবলমাত্র অ্যাপ্লিকেশনটির গতি কমিয়ে দেয়। অনডাস্ট্রয়ে রিসাইক্লিং বিটম্যাপগুলি আমার পক্ষেও কার্যকর হয়নি।

কেবলমাত্র এখন যা কাজ করে তা হ'ল সমস্ত বিটম্যাপের একটি স্থিতির তালিকা থাকা যাতে পুনরায় চালু হওয়ার পরে বিটম্যাপগুলি টিকে থাকে। এবং পুনরায় আরম্ভ করা হলে কার্যকলাপ প্রতিবার নতুন তৈরি করার পরিবর্তে কেবল সংরক্ষিত বিটম্যাপগুলি ব্যবহার করুন।

আমার ক্ষেত্রে কোডটি এরকম দেখাচ্ছে:

private static BitmapDrawable currentBGDrawable;

if (new File(uriString).exists()) {
    if (!uriString.equals(currentBGUri)) {
        freeBackground();
        bg = BitmapFactory.decodeFile(uriString);

        currentBGUri = uriString;
        bgDrawable = new BitmapDrawable(bg);
        currentBGDrawable = bgDrawable;
    } else {
        bgDrawable = currentBGDrawable;
    }
}

এটি কি আপনার প্রসঙ্গে ফাঁস হবে না? (ক্রিয়াকলাপের ডেটা)
রাফেল সান্ধ্যকাল

0

যুক্তিসঙ্গত আকারের সাথে ব্যাকগ্রাউন্ড চিত্রগুলি স্যুইচ করার ক্ষেত্রে আমার একই সমস্যা ছিল। নতুন ছবি তোলার আগে ইমেজভিউটি স্থির করে দিয়ে আরও ভাল ফলাফল পেয়েছি।

ImageView ivBg = (ImageView) findViewById(R.id.main_backgroundImage);
ivBg.setImageDrawable(null);
ivBg.setImageDrawable(getResources().getDrawable(R.drawable.new_picture));

0

এফডাব্লুআইডাব্লু, এখানে আমি হালকা ওজনের বিটম্যাপ-ক্যাশে কোড করেছি যা কয়েক মাস ধরে ব্যবহার করেছি। এটি সর্বদা-ঘণ্টা এবং শিসগুলি নয়, সুতরাং কোডটি ব্যবহার করার আগে কোডটি পড়ুন।

/**
 * Lightweight cache for Bitmap objects. 
 * 
 * There is no thread-safety built into this class. 
 * 
 * Note: you may wish to create bitmaps using the application-context, rather than the activity-context. 
 * I believe the activity-context has a reference to the Activity object. 
 * So for as long as the bitmap exists, it will have an indirect link to the activity, 
 * and prevent the garbaage collector from disposing the activity object, leading to memory leaks. 
 */
public class BitmapCache { 

    private Hashtable<String,ArrayList<Bitmap>> hashtable = new Hashtable<String, ArrayList<Bitmap>>();  

    private StringBuilder sb = new StringBuilder(); 

    public BitmapCache() { 
    } 

    /**
     * A Bitmap with the given width and height will be returned. 
     * It is removed from the cache. 
     * 
     * An attempt is made to return the correct config, but for unusual configs (as at 30may13) this might not happen.  
     * 
     * Note that thread-safety is the caller's responsibility. 
     */
    public Bitmap get(int width, int height, Bitmap.Config config) { 
        String key = getKey(width, height, config); 
        ArrayList<Bitmap> list = getList(key); 
        int listSize = list.size();
        if (listSize>0) { 
            return list.remove(listSize-1); 
        } else { 
            try { 
                return Bitmap.createBitmap(width, height, config);
            } catch (RuntimeException e) { 
                // TODO: Test appendHockeyApp() works. 
                App.appendHockeyApp("BitmapCache has "+hashtable.size()+":"+listSize+" request "+width+"x"+height); 
                throw e ; 
            }
        }
    }

    /**
     * Puts a Bitmap object into the cache. 
     * 
     * Note that thread-safety is the caller's responsibility. 
     */
    public void put(Bitmap bitmap) { 
        if (bitmap==null) return ; 
        String key = getKey(bitmap); 
        ArrayList<Bitmap> list = getList(key); 
        list.add(bitmap); 
    }

    private ArrayList<Bitmap> getList(String key) {
        ArrayList<Bitmap> list = hashtable.get(key);
        if (list==null) { 
            list = new ArrayList<Bitmap>(); 
            hashtable.put(key, list); 
        }
        return list;
    } 

    private String getKey(Bitmap bitmap) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Config config = bitmap.getConfig();
        return getKey(width, height, config);
    }

    private String getKey(int width, int height, Config config) {
        sb.setLength(0); 
        sb.append(width); 
        sb.append("x"); 
        sb.append(height); 
        sb.append(" "); 
        switch (config) {
        case ALPHA_8:
            sb.append("ALPHA_8"); 
            break;
        case ARGB_4444:
            sb.append("ARGB_4444"); 
            break;
        case ARGB_8888:
            sb.append("ARGB_8888"); 
            break;
        case RGB_565:
            sb.append("RGB_565"); 
            break;
        default:
            sb.append("unknown"); 
            break; 
        }
        return sb.toString();
    }

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.