অ্যান্ড্রয়েড যখন বিরতি দেয় তখন ওপেনএল প্রসঙ্গটি হারাতে হবে?


40

অ্যান্ড্রয়েড ডকুমেন্টেশন বলে:

EGL রেন্ডারিং প্রসঙ্গটি হারিয়ে যাবে এমন পরিস্থিতি রয়েছে। ঘুমানোর পরে ডিভাইস ঘুম থেকে ওঠার পরে সাধারণত এটি ঘটে। যখন ইজিএল প্রসঙ্গটি নষ্ট হয়ে যায়, সেই প্রসঙ্গে যুক্ত সমস্ত ওপেনজিএল সংস্থান (যেমন টেক্সচার) স্বয়ংক্রিয়ভাবে মোছা হবে। রেন্ডারিংটি সঠিকভাবে চালিয়ে যেতে, কোনও রেন্ডারারের অবশ্যই তার হারিয়ে যাওয়া যে সমস্ত সংস্থান প্রয়োজন তা পুনরায় তৈরি করতে হবে। অনসরাসফ্রেসেটেড (জিএল 10, ইজিএলকনফিগ) পদ্ধতি এটি করার জন্য একটি সুবিধাজনক জায়গা।

তবে ওপেনজিএল প্রসঙ্গে সমস্ত টেক্সচার পুনরায় লোড করা উভয়ই একটি ব্যথা এবং বিরতি দেওয়ার পরে অ্যাপটিতে প্রবেশের সময় ব্যবহারকারীর জন্য গেমের অভিজ্ঞতাকে আঘাত করে। আমি জানি যে "অ্যাংরি পাখি" কোনওভাবে এড়িয়ে চলে, আমি কীভাবে এটি সম্পাদন করতে পারি তার জন্য পরামর্শগুলি খুঁজছি?

আমি অ্যান্ড্রয়েড এনডিকে আর 5 (ক্রিস্টাক্স সংস্করণ।) নিয়ে কাজ করছি আমি সমস্যার সম্ভাব্য এই হ্যাকটি পেয়েছি তবে আমি একটি সম্পূর্ণ কাস্টম এসডিকে সংস্করণ তৈরি করা এড়াতে চাইছি।


ঘুমন্ত এবং জাগ্রত হওয়ার বিষয়টি ডিভাইসে রেফার করা হয় যাতে ব্যবহারকারী কেবল আপনার গেমটি থামিয়ে দেয় বা প্রক্রিয়াকরণে ইজিএল প্রসঙ্গটি ছাড়িয়ে যায় loose
Ali1S232

উত্তর:


22

রেপ্লিকা দ্বীপে জিএলসুরফেসভিউয়ের একটি সংশোধিত সংস্করণ রয়েছে যা এই সমস্যাটি (এবং পূর্ববর্তী অ্যান্ড্রয়েড সংস্করণগুলির সাথে কাজ করে) নিয়ে কাজ করে। ক্রিস প্রুয়েটের মতে :

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

আপনার ডিফল্ট GLSurfaceView ব্যবহার করা উচিত। আমার যদি অবশ্যই একই রকম কার্যকারিতা থাকে তবে আপনি আমার দিকে তাকাতে পারেন। তবে আমি যা করেছি তা হ্যান্ডসেটগুলিতে সমস্ত ধরণের ভয়ঙ্কর ড্রাইভারের বাগ উন্মুক্ত করে দিয়েছি (সেই ফাইলটির শেষের দিকে খুব দীর্ঘ মন্তব্য দেখুন) এবং আপনি কেবলমাত্র ডিফল্ট ব্যবহার করে এই সমস্ত জগাখিচুড়ি এড়াতে পারবেন।

সম্পাদনা: আমি ঠিক বুঝতে পেরেছি যে আপনি ইতিমধ্যে একটি অনুরূপ হ্যাকের লিঙ্কটি পোস্ট করেছেন। আমি মনে করি না মধুচক্রের আগে কোনও অন্তর্নির্মিত সমাধান আছে। রেপ্লিকা দ্বীপ একটি জনপ্রিয় খেলা যা অনেক ডিভাইসে কাজ করে এবং আপনি ক্রিসের বাস্তবায়ন এবং মন্তব্যগুলি সহায়ক বলে মনে করতে পারেন।


1
এটিকে অবহেলা করার জন্য বিভিন্ন পদ্ধতির চেষ্টা করার পরে, আমি সিদ্ধান্ত নিয়েছি যে প্রসঙ্গটি পুনরায় তৈরি করতে অ্যাপ্লিকেশনটি পুনরায় তৈরি করাই সেরা সমাধান। এটি এমন একটি অপ্রয়োজনীয় পদ্ধতি তবে এটির মতো দেখে মনে হচ্ছে না যে কোনও ভাল সমাধান কোড. google.com/p/android/issues/detail?id=12774
নিক গটচ ২

9

আমি এর আরও একটি উত্তর যুক্ত করতে চাই যা ক্রিস প্রুয়েট (রেপ্লিকা দ্বীপ, উইন্ড-আপ নাইট, ইত্যাদি) দ্বারা আমার কাছে এক বা দু'বছর আগে দিয়েছিল। এটি এখানে 2013 সালে বিশেষত কার্যকর যেহেতু সেটপ্রিজারগ্লিকনটেক্সটঅনপজ (সত্য) 4.3-এ কাজ করছে বলে মনে হচ্ছে না। (আমি এটি সম্পর্কে ভুল হতে পারি তবে ২০১১ সালে শেষবার স্পর্শ করা গেমের কোড আপডেট করার সাথে সাথে এখনই এটি আমার কাছে দেখাচ্ছে)।

মূলত কৌতুকটি হল আপনার ক্রিয়াকলাপের অনপজ () থেকে আপনার জিএলসুরফেসভিউটি ভিউ হায়ারার্কি থেকে আলাদা করা ach যেহেতু এটি পজ () চালানোর পয়েন্টে শ্রেনীর স্তরের অংশে নেই, প্রসঙ্গটি কখনই ধ্বংস হয় না।

সুতরাং আপনার ক্রিয়াকলাপের অনপেজ () এর মতো দেখতে পাওয়া উচিত:

@Override
public void onPause() {
    view.setVisibility(View.GONE);
    super.onPause();
    ...
}

আর তুমি অনুক্রমের আপনার GLSurfaceView পুনঃস্থাপন না onResume (সম্ভাব্য) কিন্তু onWindowFocusChanged () থেকে:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus && view.getVisibility() == View.GONE) {
         view.setVisibility(View.VISIBLE);
    }
    ...
}

নোট করুন যে আপনি কখনই জিএলসুরফেসভিউ'র অনপেজ () এবং অনরেসিউম () এবং কল করেন না এটি সরকারী এসডিকে জিএলসুরফেসভিউ, কোনও হ্যাক-আপ বিকল্প সংস্করণ প্রয়োজন নেই।


আসলে এই পদ্ধতির কাজ বলে মনে হচ্ছে না। ক্রিস প্রুয়েট এটি ইউনিটির সংমিশ্রণে ব্যবহার করেছেন, এটি কি সম্ভব যে এই কাজটি দেশীয় প্রকল্পগুলিতে কাজ করছে না? তবে কেবল জিএলভিউ.অন.পজ () কে কল করা কল্পনা করছে না বলে মনে হচ্ছে !? অন্য কেউ আছেন যারা এটি নিশ্চিত করতে পারেন?
sjkm

এটি আমার জন্য অ্যান্ড্রয়েড ২.২ ওপেনগিল ইএস লক্ষ্যবস্তুতে কাজ করেছিল। এটি অন্যান্য ডিভাইসে কীভাবে সম্পাদন করে তা নিশ্চিত নয়। আমার কাছে একটি এলজি জি 2 ডি 802 ফোন রয়েছে। কেউ কি জানেন যে এটি সাধারণ সমাধান কিনা?
পিক্সেল

7

<rant> আমি এই সমস্যার জন্য প্রচুর সময় ব্যয় করেছি, আমি অনেকগুলি বিভিন্ন সমাধানের চেষ্টা করেছি এবং আজ পর্যন্ত কেউই কাজ করেনি, আমি মনে করি এটি এমনকি আমি দেখেছি এমন একটি অত্যন্ত ভয়ঙ্কর ডিজাইনের সিদ্ধান্ত, তবে অ্যান্ড্রয়েড দল থেকে এসেছি আমি নই সত্যিই অবাক। </ rant>

সুতরাং, সমাধানটি হ'ল eglContext সদস্যকে উপরের দিকে সরানো এবং এটিকে স্থিতিশীল (গ্লোবাল) তৈরি করা যাতে এটি ধ্বংস হয় না, তবে আপনাকে কেবল আবার এটি তৈরি করার আগে এটি বাতিল বা না তা পরীক্ষা করে দেখতে হবে।

এখনও অবধি এই সমাধানটি আমাদের পক্ষে কাজ করে বলে মনে হচ্ছে এবং 2005 এর ডিভাইসে এটি ভেঙে যায় কিনা সে বিষয়ে আমাদের কোনও খেয়াল নেই।


4

মধুচক্র এপিআই ব্যবহার করুন। আপনার ওজিএল প্রসঙ্গে সংরক্ষণ করার জন্য একটি বিকল্প রয়েছে। অন্যথায়, আপনাকে আপনার প্রসঙ্গটি পুনরায় লোড করা দরকার। এটি কঠিন বা বেদনাদায়ক নয়।

আপনার বুঝতে হবে যে দুটি ক্ষেত্রে রয়েছে (অ্যান্ড্রয়েড ২.১):

  • স্ক্রিন বিরতি: আপনার অ্যাপ্লিকেশন সর্বদা প্রথম এক => হ্যাক উপলব্ধ
  • অ্যাপ্লিকেশন বিরতি: আরও একটি সামনের অ্যাপ্লিকেশন রয়েছে => কোনও সমাধান নেই

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

দ্রষ্টব্য 2: হানিকম্ব ফাংশনটি সেট করা আছে প্রিজারিজইএলএল কনটেক্সটঅনপস


1
আমি অ্যান্ড্রয়েড এনডিকে একটি সি ++ গেম পোর্ট করছি যা প্রসঙ্গটি সহজেই পুনরায় লোড করার জন্য ডিজাইন করা হয়নি, তবে আমার পক্ষে কমপক্ষে এটি কিছুটা কঠিন। অসুবিধাগুলি অন্যদিকে, পুনরায় লোড করার ফলে এমন বিলম্ব সংঘটিত হবে যা আমাদের অন্যান্য ডিভাইসে উপস্থিত নেই (আইফোন, পিএসপি, ডিএস, ইত্যাদি।) মধুচক্রের সমাধানগুলি শুনে খুব খুশি হয়েছে তবে দুর্ভাগ্যক্রমে আমাদের ২.১+ সমর্থন করতে হবে
নিক গটছ

1
এটি তার প্রশ্নের কোনও উত্তর দেয় না।

1
যদি আপনি বুঝতে না পারেন, আপনি এটি করতে পারবেন না।
এলিস

2

এখানে কয়েকটি উত্তর অ্যান্ড্রয়েডে ওপেনজিএল ইএস এর প্রাথমিক ব্যবহারের জন্য যুক্তিসঙ্গত। প্রথম GLES ডিভাইসগুলি কেবল একটি একক প্রসঙ্গকে সমর্থন করেছিল, তাই GLSurfaceView আক্রমণাত্মকভাবে রাষ্ট্র ত্যাগ করার জন্য ডিজাইন করা হয়েছিল। অন্যথায় করতে জিএলসুরফেসভিউকে বোঝানো সহজ নয়।

অ্যান্ড্রয়েডের আরও সাম্প্রতিক সংস্করণগুলির জন্য (সম্ভবত জিএলইএস ২.০ ব্যবহার করে কিছু রয়েছে), সবচেয়ে ভাল উত্তর হ'ল একটি সরল সারফেসভিউ ব্যবহার করা এবং আপনার নিজের ইজিএল এবং থ্রেড পরিচালনা করা। আপনি GLES একাধিক উদাহরণ একটা সমভূমি SurfaceView সঙ্গে ব্যবহার জানতে পারেন Grafika তৈরি ও EGL প্রেক্ষিতে অন্তক জন্য সহজ ক্লাস একটি লাইব্রেরি সহ।

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

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