Android SDK AsyncTask doInBackগ্রাউন্ড চলছে না (সাবক্লাস)


90

15/2/2012 পর্যন্ত আমার এখনও ভাল ব্যাখ্যা বা এটি কার্যকর না হওয়ার কারণ খুঁজে পাই। কোনও সমাধানের নিকটতমটি হ'ল traditional তিহ্যবাহী থ্রেড পদ্ধতির ব্যবহার করা , তবে তারপরে অ্যান্ড্রয়েড এসডিকে কাজ করে না এমন একটি বর্গ কেন অন্তর্ভুক্ত করবেন?

ইভেন 'তাই!

আমার একটি অ্যাসিঙ্কটাস্ক সাবক্লাস রয়েছে:

// ParseListener had a callback which was called when an item was parsed in a
// RSS-xml, but as stated further down it is not used at all right now.
private class xmlAsync extends AsyncTask<String, RSSItem, Void> implements ParseListener

এটি এভাবেই কার্যকর করা হয়:

xmlAsync xmlThread = new xmlAsync();

xmlThread.execute("http://www.nothing.com");

এখন এই সাবক্লাসটি একটি সামান্য ত্রুটিতে চলেছে। পূর্বে এটি কিছু এক্সএমএল-পার্সিং করত, কিন্তু যখন আমি লক্ষ্য করেছি যে এটি ডাইনব্যাকগ্রাউন্ড () বলা হয় নি তখন আমি একে একে একে একে নামিয়ে দিয়েছি, অবশেষে ঠিক এইটি দিয়ে শেষ করছি:

@Override
protected Void doInBackground(String... params) 
{
    Log.v(TAG, "doInBackground");
        return null;
}

কোন কারণে কোনও কারণে লগইন হয়নি। তবে আমি এটি যুক্ত করেছি:

@Override
protected void onPreExecute() 
{
        Log.v(TAG, "onPreExecute");
        super.onPreExecute();
}

এবং থ্রেড সম্পাদন করার সময় সেই লাইনটি অবশ্যই লগ হয়। সুতরাং কোনওভাবে অনিয়ন্ত্রিত () বলা হয় তবে doInBackground () নয় । আমার একই সাথে অন্য একটি অ্যাসিঙ্কটাস্ক পটভূমিতে চলছে যা ঠিক কাজ করে।

আমি বর্তমানে উত্তর মেরুর নিকটবর্তী এমুলেটর, এসডিকে সংস্করণ 15, গ্রহন, ম্যাক ওএস এক্স 10.7.2 এ অ্যাপটি চালাচ্ছি।

সম্পাদনা:

@Override
    protected void onProgressUpdate(RSSItem... values) {

        if(values[0] == null)
        {
                            // activity function which merely creates a dialog
            showInputError();
        }
        else
        {

            Log.v(TAG, "adding "+values[0].toString());
            _tableManager.addRSSItem(values[0]);
        }


        super.onProgressUpdate(values);
    }

_tableManager.addRSSItem () কমপক্ষে একটি এসকিউএলডিটাবেসে একটি সারি যুক্ত করে, ক্রিয়াকলাপের প্রসঙ্গে শুরু করে। ইন্টারফেস পার্সলিস্টনারের কলব্যাক দ্বারা পাবলিশপ্রোগ্রেস () বলা হয়। যাইহোক, যেহেতু আমি ডইইনব্যাকগ্রাউন্ড () এ লগ.ভ ছাড়াও কিছু করি না আমি প্রথমে এটি আনার জন্যও অপ্রয়োজনীয় দেখতে পেয়েছি।

সম্পাদনা 2:

ঠিক আছে, পুরোপুরি পরিষ্কার করার জন্য, এটি অন্যান্য অ্যাসিঙ্কটাস্ক, একই ক্রিয়াকলাপে চালিত এবং পুরোপুরি সূক্ষ্মভাবে কাজ করে।

private class dbAsync extends AsyncTask<Void, RSSItem, Void>
{
    Integer prevCount;
    boolean run;

    @Override
    protected void onPreExecute() {
        run = true;
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        run = true;
        prevCount = 0;

        while(run)
        {
            ArrayList<RSSItem> items = _tableManager.getAllItems();

            if(items != null)
            {
                if(items.size() > prevCount)
                {
                    Log.v("db Thread", "Found new item(s)!");
                    prevCount = items.size();

                    RSSItem[] itemsArray = new RSSItem[items.size()];

                    publishProgress(items.toArray(itemsArray));
                }
            }               

            SystemClock.sleep(5000);
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(RSSItem... values) {

        ArrayList<RSSItem> list = new ArrayList<RSSItem>();

        for(int i = 0; i < values.length; i++)
        {
            list.add(i, values[i]);
        }

        setItemsAndUpdateList(list);

        super.onProgressUpdate(values);
    }

    @Override
    protected void onCancelled() {
        run = false;

        super.onCancelled();
    }
}

সম্পাদনা 3:

দীর্ঘশ্বাস, দুঃখিত আমি প্রশ্ন জিজ্ঞাসা করতে খারাপ। তবে এখানে টাস্কগুলির সূচনাটি।

xmlAsync _xmlParseThread;
dbAsync _dbLookup;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

_dbLookup = new dbAsync();
_dbLookup.execute();

_xmlParseThread = new xmlAsync();       
_xmlParseThread.execute("http://www.nothing.com", null);
}

টাস্ক শেষ হওয়ার আগেই কী কার্যকলাপটি শেষ করা সম্ভব?
পল নিকোনোইজিক

অত্যন্ত সম্ভাবনা নেই। সেক্ষেত্রে আমার অন্য থ্রেড ঠিক চলছে না? এবং এই মুহূর্তে আমার কেবলমাত্র একটি ক্রিয়াকলাপ রয়েছে।
SeruK

4
আমার অ্যাপ্লিকেশনটিতেও একই সমস্যা রয়েছে - ডুআইনব্যাকগ্রাউন্ডটি হয় না বলা হয় বা খুব দীর্ঘ বিলম্বের সাথে ডাকা হয় না। এখানে আমার সীমাবদ্ধ পর্যবেক্ষণটি দেওয়া হয়েছে: ঠিক একই কোডটি অ্যান্ড্রয়েড ২.৩.৩ স্মার্টফোন এবং একটি অ্যান্ড্রয়েড ২.৩.৩ এমুলেটরটিতে নির্বিঘ্নে কাজ করে, তবে অ্যান্ড্রয়েড 4.0.০.৩ ট্যাবলেট এবং অ্যান্ড্রয়েড 4..০ এক্সএক্স এমুলেটরগুলিতে এই সমস্যা রয়েছে। এই সমস্যাটি অ্যান্ড্রয়েডের নতুন সংস্করণগুলিতে প্রবর্তিত হয়েছিল তা উপসংহারে অত্যন্ত লোভনীয়।
হংক

দুঃখিত, তবে আমি এই সমস্যাটি উল্লেখ করতে ভুলে গেছি কেবলমাত্র একটি ক্রিয়াকলাপের দ্বিতীয় অ্যাসিঙ্কটাস্কের সাথে প্রথম অ্যাসিঙ্কটাস্ক সর্বদা ভাল কাজ করে।
হংকং

হংক, আপনি ম্যাথিউয়ের উত্তরটি চেষ্টা করেছেন? আমি বেশিরভাগই অ্যান্ড্রয়েড গেম এটিএম থেকে বাইরে এসেছি এবং কিছুক্ষণ এটি নিয়ে কাজ করি নি, তাই তার উত্তরগুলি আসলে কাজ করে কিনা তা আমি বলতে পারি না। যদি এটি আপনার পক্ষে না হয় তবে তার উত্তরটি গ্রহণ করা আমার পক্ষে খারাপ ছিল ...
SeruK

উত্তর:


107

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

আচরণটি AsyncTask().execute();অ্যান্ড্রয়েড সংস্করণগুলির মাধ্যমে পরিবর্তিত হয়েছে। আগে ডোনাট (অ্যান্ড্রয়েড: 1.6 এপিআই: 4) কার্য, ধারাবাহিকভাবে মৃত্যুদন্ড কার্যকর করা হয় থেকে ডোনাট করার জিনজার ব্রেড (অ্যান্ড্রয়েড: 2.3 এপিআই: 9) কর্ম সামঞ্জস্যপূর্ণ মৃত্যুদন্ড কার্যকর; হানিকম্ব যেহেতু (অ্যান্ড্রয়েড: API.০ এপিআই: ১১) মৃত্যুদন্ড কার্যকর করে তা সিক্যুয়ালটিতে ফিরে গেছে; AsyncTask().executeOnExecutor(Executor)সমান্তরাল সম্পাদনের জন্য একটি নতুন পদ্ধতি যুক্ত করা হয়েছিল।

অনুক্রমিক প্রক্রিয়াজাতকরণে সমস্ত অ্যাসিঙ্ক কার্য একক থ্রেডে চালিত হয় এবং সুতরাং পূর্ববর্তী কার্য শেষ হওয়ার আগে অপেক্ষা করতে হবে। আপনার যদি তাত্ক্ষণিক কোড কার্যকর করতে হয় তবে আপনার পৃথক থ্রেডে সমান্তরালে প্রক্রিয়াজাতকরণের প্রয়োজন।

অ্যাসিঙ্কটাস্কের সাথে সিরিয়াল এক্সিকিউশনটি ডোনট এবং হানিকম্ব সংস্করণগুলির মধ্যে পাওয়া যায় না, যখন ডানটের আগে সমান্তরাল সম্পাদনা পাওয়া যায় না।

ডোনাটের পরে সমান্তরাল প্রক্রিয়াকরণের জন্য: বিল্ড সংস্করণটি পরীক্ষা করুন এবং সেই ব্যবহারের ভিত্তিতে .execute () বা .executeOnExecutor () পদ্ধতির উপর ভিত্তি করে। নিম্নলিখিত কোডটি সহায়তা করতে পারে ...

AsyncTask<Void,Void,Void> myTask = new AsyncTask<Void,Void,Void>() { ... }; // ... your AsyncTask code goes here
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
    myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
    myTask.execute();

NOTE:ফাংশন .executeOnExecutor()যদি চেক আছে targetSdkVersionপ্রকল্প চেয়ে বা সমান কম HONEYCOMB_MR1তারপর, এটা নির্বাহক বাধ্য হতে (7: 2.1 এপিআই অ্যান্ড্রয়েড) THREAD_POOL_EXECUTOR(যা পোস্ট মউচাক ক্রমানুশারে কার্যগুলি রান)।
আপনি যদি কোনও সংজ্ঞা না দিয়ে থাকেন targetSdkVersionতবে minSdkVersionস্বয়ংক্রিয়ভাবে এটি হিসাবে বিবেচিত হবে targetSdkVersion
সুতরাং আপনার মধুচক্র পোস্টে সমান্তরালভাবে আপনার অ্যাসিঙ্কটাস্ক চালানোর জন্য আপনি targetSdkVersionখালি রাখতে পারবেন না ।


4
খুব ভাল উত্তর। ম্যাথিউয়ের ভুল না হলেও আমি এটি গ্রহণ করছি, যেহেতু আপনি একগুচ্ছ গুরুত্বপূর্ণ তথ্য যুক্ত করেন।
SeruK

@ নাশকে অনেক ধন্যবাদ এটি সত্যই খুব সহায়ক। আমি এই একই ইস্যু নিয়ে 3 দিন ধরে লড়াই করে যাচ্ছিলাম। আবার ধন্যবাদ :)

আমার দিন বাঁচা! এই উত্তরটি খুঁজে পাওয়া সহজ হোক W
zjk

4
আরে @ নাশ, আমার সমস্যাটি কিছুটা বিশ্রী। আজকের আগে আমি AsyncTask এ .execute () পদ্ধতিটি ব্যবহার করছিলাম এবং কোডটি পুরোপুরি কার্যকর ছিল। তবে আজ আমি সমস্যাটি পেয়েছি - নিয়ন্ত্রণটি doInBackground () পদ্ধতিতে যায় না। আপনার প্রদত্ত সমাধানটি কাজ করা সত্ত্বেও, আমি বিস্মিত হয়েছি যে সমাধান ছাড়াই এটি কীভাবে কাজ করে। আমি আগে এবং এখন একই ডিভাইসগুলির ব্যবহার করছি using
রবি সিসোদিয়া

কেন এইভাবে করা উচিত? এটি প্রত্যাশা অনুযায়ী কাজ করে না কেন? :(
নিকোলে আর

160

আপনার এই উত্তরটি চেকআউট করা উচিত: https://stackoverflow.com/a/10406894/347565 এবং এতে অন্তর্ভুক্ত গুগল গ্রুপগুলির লিঙ্ক।

আপনার মতো আমারও একই সমস্যা ছিল, কেন এটি কাজ করছে না তা এখনও পরিষ্কার নয়, তবে আমি আমার কোডটি এভাবে পরিবর্তন করেছি এবং সমস্যাটি চলে গেছে:

ASyncTask<Void,Void,Void> my_task = new ASyncTask<Void,Void,Void>() { ... };
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    my_task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
else
    my_task.execute((Void[])null);

আমি এই পোস্টে ফিরে তাকানোর খুব খারাপ হয়েছে; আমি দীর্ঘদিন থেকে প্রকল্প থেকে সরে এসেছি। আমি কেবল এটি উত্তর হিসাবে গ্রহণ করব কারণ লোকেরা মনে হয় এটি কাজ করে।
SeruK

এটি এখনই আমার জন্য কাজ করেছে তবে আমি আশা করি কেন বুঝতে পারছি। এটি আগে কার্যকর করার সাথে সাথে কাজ করে তখন এটি বন্ধ হয়ে যায়। একটি জিনিস যা আমি করছি তা একই অ্যাসিনটাস্কের পস্টএক্সেকিউটের ভিতরে একটি নতুন অ্যাসিনটাস্ক শুরু করছে (যার অর্থ আমি এটি পুনরাবৃত্তি বলছি) সম্ভবত এটি সমস্যার সাথে যুক্ত?
স্টিভ

আমি মনে করি এটা আপনারা সবাই ব্যাখ্যা দিতে হবে আপনি প্রয়োজন: commonsware.com/blog/2012/04/20/...
Matthieu

4
@ ম্যাথিউ: স্যার, আমি আপনাকে যথেষ্ট ধন্যবাদ জানাতে পারি না !!! আমি কয়েক ঘন্টা ধরে এই সমস্যায় মাথা ঠাপিয়ে যাচ্ছিলাম এবং আপনার সমাধানটি মনোমুগ্ধকর মতো কাজ করে! চমত্কার উত্তরের জন্য আপনাকে অনেক ধন্যবাদ। আমি আশা করি আমি একাধিক upvote দিতে পারে !!
স্বয়াম


9

আপনি এটি দুটি উপায়ে করতে পারেন:

উপায় 1 :

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) // Above Api Level 13
  {
      asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
  }
else // Below Api Level 13
  {
      asyncTask.execute();
  }

উপায় 1 ক্ষেত্রে আপনার পক্ষে কাজ না করে উপায় 2 চেষ্টা করুন ।

উপায় 2 :

int mCorePoolSize = 60;
int mMaximumPoolSize = 80;
int mKeepAliveTime = 10;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(mMaximumPoolSize);
Executor mCustomThreadPoolExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, mKeepAliveTime, TimeUnit.SECONDS, workQueue);
asyncTask.executeOnExecutor(mCustomThreadPoolExecutor);

আশা করি এটা তোমাকে সাহায্য করবে।


সুপার ডুড এর কাজ করছে কিন্তু পরবর্তী পরবর্তী এসিন্যাকের কাজগুলি যা এসিঙ্কটাস্ক ব্যবহার করছে TH থ্রিএডিডিপিওএল_এক্সইকিউটারগুলি ব্যর্থ হচ্ছে, তাই আমার ধারণা প্রজেক্টের সমস্ত কাস্টমএক্সেক্টর দিয়ে পরিবর্তন করতে হবে :(
কুমার

@ভিনু, আমি আপনাকে অ্যাসিঙ্কটাস্ক কার্যকর করার জন্য সাধারণ অ্যাসিঙ্ক টাস্ক এবং সাধারণ পদ্ধতি ব্যবহার করার পরামর্শ দিচ্ছি। আশা করি এটা তোমাকে সাহায্য করবে।
হিরেন প্যাটেল

4
আরে এটা আমাকে অনেক সাহায্য করেছে! ধন্যবাদ!
জাস্টিন এবি

6

আমার একই সমস্যা ছিল: আমি প্রথমটিতে "এক্সিকিউট" বলার পরে দ্বিতীয় অ্যাসিঙ্কটাস্ককে কার্যকর করতে পারি না: doInBackground কেবল প্রথমটির জন্য ডাকা হয়।

কেন এমনটি হয় তার উত্তর দেওয়ার জন্য এই উত্তরটি পরীক্ষা করুন (এসডিকে নির্ভর বিভিন্ন আচরণ)

যাইহোক, আপনার ক্ষেত্রে, এই বাধাটি এক্সিকিউটঅনএক্সেকিউটর ব্যবহার করে এড়ানো যায় (3.0 থেকে শুরু করে আমার কাছে 4.0.3 ব্যবহার করে কাজ করেছে) তবে থ্রেড পুলের আকার এবং সীমাবদ্ধতার সীমাবদ্ধতা থেকে সাবধান থাকুন।

আপনি কি এরকম কিছু চেষ্টা করতে পারেন:

xmlAsync _xmlParseThread;
dbAsync _dbLookup;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

_dbLookup = new dbAsync();
_dbLookup.execute();

_xmlParseThread = new xmlAsync();       
_xmlParseThread.executeOnExecutor(_dbLookup.THREAD_POOL_EXECUTOR
 ,"http://www.nothing.com", null);
}

আপনার আপডেট প্রশ্নের জন্য: ডক্সে এটি ব্যাখ্যা করা হয়েছে মূলত কেবলমাত্র আন্তরিকতার মতো মাল্টিথ্রেডিং থেকে আসা সমস্ত সমস্যা এড়াতে ....


5

একটি জিনিস যা আমি জানতে চাই এবং এটি আসলে আপনার সমস্যাটি সমাধান করতে পারে আপনি কোথায় আপনার ক্লাসের উদাহরণটি ইনস্ট্যান্ট করছেন এবং এক্সিকিউট () পদ্ধতিটি কল করছেন? আপনি যদি অ্যাসিঙ্কটাস্কের ডকুমেন্টেশনটি পড়ে থাকেন তবে সেই উভয় ক্রিয়াকলাপই মূল ইউআই থ্রেডে হওয়া দরকার। আপনি যদি অন্য কোনও থ্রেড থেকে নিজের অবজেক্টটি তৈরি করছেন এবং এক্সিকিউট করার আহ্বান জানাচ্ছেন, তবে অনপ্রি এক্সেকিউট চালিত হতে পারে, আমি এখানে 100% নির্দিষ্ট নই, তবে পটভূমি থ্রেডটি তৈরি এবং কার্যকর করা হবে না।

যদি আপনি পটভূমির থ্রেড থেকে আপনার অ্যাসিঙ্কটাস্কের উদাহরণ তৈরি করছেন বা প্রধান UI থ্রেডে অন্য কোনও ক্রিয়াকলাপ না ঘটে থাকে তবে আপনি এই পদ্ধতিটি ব্যবহার করে বিবেচনা করতে পারেন: Activity.runOnUiThread (চলমান)

সেই পদ্ধতিটি কল করতে আপনার চলমান ক্রিয়াকলাপের কোনও অ্যাক্সেসের প্রয়োজন হবে, তবে এটি আপনাকে ইউআই থ্রেডে ইউআই থ্রেডে চলমান না এমন অন্য কোনও কোড থেকে কোড চালানোর অনুমতি দেবে।

আশা করি তা বোধগম্য হয়। আমি যদি আরও সাহায্য করতে পারি তবে আমাকে জানান।

ডেভিড


আপনার উত্তরে যুক্ত করার সাথে এই থ্রেডের একটি আকর্ষণীয় উত্তর রয়েছে stackoverflow.com/questions/4080808/…
manjusg

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

@ মানজুসগ আমি সমস্ত বিষয় বিবেচনা করেছি যে অ্যাসিঙ্কটাস্ক অস্থির হওয়ার সাথে সাথে এর কিছু করার ছিল, যখন বেশ কয়েকটি এক সাথে চালানো হতে পারে তখন অতিরিক্ত অনেক বেশি। যদি তাই হয় তবে কেন?
SeruK

টানা তিনবার দ্রুত পোস্ট করার আশেপাশে এসও এর নীতিগুলি কী তা সত্যিই আমি জানি না, তবে আমি এটি অন্য থ্রেডে পেয়েছি ... foo.jasonhudgins.com/2010/05/limitations-of-asynctask.html "AsyncTask ব্যবহার করে 10 টি উপাদানের হার্ড-কোডড সীমা সহ স্থিতিশীল অভ্যন্তরীণ কাজের সারি। " এটি কিছু প্রমাণ করতে পারে তবে আমার কাছে কেবল দু'টি উদাহরণ অ্যাসিঙ্কটাস্ক-সাবক্লাস রয়েছে! আমি সত্যিই সাধারণ থ্রেডিং পদ্ধতিগুলি এড়াতে চাই কারণ শেষ পর্যন্ত ডেরিতে প্রচুর পরিমাণে পার্সিং করা হবে।
SeruK

2

অ্যান্ড্রয়েড হয় নিষ্ঠুর! আমি এটি বিশ্বাস করতে পারি না, কি ফ্লিকে বাস্তবায়ন যা প্রতিদিন থেকে আজকে পরিবর্তিত হয়। একদিন এটির একক থ্রেড, পরের তার 5 টি অন্যান্য 128।

যাইহোক, এখানে স্টক অ্যাসিঙ্কটাস্কের প্রতিস্থাপনের প্রায় এক ড্রপ। আপনি চাইলে এটিকে এসিঙ্কটাস্কও বলতে পারেন, তবে এতে বিভ্রান্তি এড়াতে এর নাম থ্রেডডেনসিঙ্কটাস্ক বলে। এক্সিকিউট করার পরিবর্তে আপনাকে এক্সিকিউটিস্টার্ট () কল করতে হবে কারণ এক্সিকিউট () চূড়ান্ত।

/**
 * @author Kevin Kowalewski
 *
 */
public abstract class ThreadedAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { 
    public AsyncTask<Params, Progress, Result> executeStart(Params... params){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
            return executePostHoneycomb(params);
        }else{
            return super.execute(params);
        }
    }


    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private AsyncTask<Params, Progress, Result> executePostHoneycomb(Params... params){
        return super.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); 
    }
}

অপেক্ষা করুন, আপনি বলছেন না যে অ্যান্ড্রয়েডের কয়েকটি সংস্করণ অ্যাসিঙ্ক অপ্সকে একটি থ্রেডে সীমাবদ্ধ করে? এটি অবিশ্বাস্যভাবে নির্বোধ হবে। (আমি কিছুদিনের জন্য অ্যান্ড্রয়েড খেলা থেকে বের চলেছি :)।)
SeruK

হ্যাঁ, অ্যান্ড্রয়েড +.০+ এ আপনি যদি অ্যাসিঙ্কটাস্ক ব্যবহার না করেন তবে THREAD_POOL_EXECUTOR আপনি কেবল একটির থ্রেড পুল পাবেন। আপনার নিজের জন্য এটি চেষ্টা করুন, দুটি অ্যাসিঙ্কটাস্ক এবং কেবলমাত্র কারওডিনব্যাকগ্রাউন্ডে ঘুমান। অ্যান্ড্রয়েড অ্যাসিঙ্কটাস্ক ডকুমেন্টেশন থেকে: "সমান্তরাল প্রয়োগের ফলে সৃষ্ট সাধারণ অ্যাপ্লিকেশন ত্রুটিগুলি এড়াতে একক থ্রেডে কার্য সম্পাদন করা হয়।"
কেভিন পার্কার 0

1

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


0

আমি মনে করি এটি এসডিকে আমার একই সমস্যা ছিল, এবং 15 থেকে 11 পর্যন্ত টার্গেট এসডিকে পরিবর্তন করার পরে, সবকিছু ঠিকঠাকভাবে কাজ করে।

sdk15 সহ, যদিও AsyncTask.Status চলমান, doInBackground কখনও বলা হয় না। আমি ইউআই থ্রেড এর সাথে কিছু করার আছে বলে আমি মনে করি।


আমি এটি অস্বীকার বা নিশ্চিত করতে পারি না কারণ এটি পরীক্ষা করার জন্য আমার কাছে এখনই সময় নেই। আমি যা বলতে পারি তা হ'ল আমি এসডিকে 15 ব্যবহার করছিলাম, সুতরাং এটি খুব সম্ভবত।
SeruK

0

ম্যাথিউয়ের উত্তরের ভিত্তিতে, আপনার অ্যাপ্লিকেশনটিতে নকল কোডটি এড়াতে যাতে এসডিকে সংস্করণের উপর নির্ভর করে আপনার সঠিকভাবে কার্যকর করতে একটি সহায়ক শ্রেণীর নীচে AsyncTask:

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Build;

public class AsyncTaskExecutor<Params, Progress, Result> {

  @SuppressLint("NewApi")
  public AsyncTask<Params, Progress, Result> execute(final AsyncTask<Params, Progress, Result> asyncTask, final Params... params){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
      return asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    }  else{
      return asyncTask.execute(params);
    }
  }

}

ব্যবহারের উদাহরণ:

public class MyTask extends AsyncTask<Void, Void, List<String>> {

...

final MyTask myTask = new MyTask();
new AsyncTaskExecutor<Void, Void, List<String>>().execute(myTask);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.