एंड्रॉइड 11 में Android AsyncTask एपीआई अपग्रेडिंग विकल्प क्या हैं?


20

EDIT : यह प्रश्न डुप्लिकेट नहीं है

  1. अभी कुछ दिन पहले ही एओएसपी की प्रतिनियुक्ति की गई थी।
  2. अन्य प्रश्न AsyncTaskLoader का उपयोग करने के बारे में AsyncTask पर है।


Google Android 11 में Android AsyncTask API को अपग्रेड कर रहा है और java.util.concurrentइसके बजाय उपयोग करने का सुझाव दे रहा है । आप यहां कमिट देख सकते हैं

 *
 * @deprecated Use the standard <code>java.util.concurrent</code> or
 *   <a href="https://developer.android.com/topic/libraries/architecture/coroutines">
 *   Kotlin concurrency utilities</a> instead.
 */
@Deprecated
public abstract class AsyncTask<Params, Progress, Result> {

यदि आप एंड्रॉइड में अतुल्यकालिक कार्यों के साथ एक पुराना कोडबेस बना रहे हैं, तो आपको भविष्य में इसे बदलने की संभावना है। मेरा प्रश्न यह है कि कोड स्निपेट का उचित प्रतिस्थापन क्या होना चाहिए जो नीचे दिखाया गया है java.util.concurrent। यह एक गतिविधि का एक स्थिर आंतरिक वर्ग है। मैं एक ऐसी चीज की तलाश में हूं, जिसके साथ काम करेंगेminSdkVersion 16

private static class LongRunningTask extends AsyncTask<String, Void, MyPojo> {
        private static final String TAG = MyActivity.LongRunningTask.class.getSimpleName();
        private WeakReference<MyActivity> activityReference;

        LongRunningTask(MyActivity context) {
            activityReference = new WeakReference<>(context);
        }

        @Override
        protected MyPojo doInBackground(String... params) {
            // Some long running task

        }

        @Override
        protected void onPostExecute(MyPojo data) {

            MyActivity activity = activityReference.get();
            activity.progressBar.setVisibility(View.GONE);
            populateData(activity, data) ;
        }     


    }

5
"पदावनत" का अर्थ है कि Google अनुशंसा कर रहा है कि आप किसी और चीज़ पर जाएँ। इसका मतलब यह नहीं है कि जल्द ही क्लास को हटा दिया जाएगा। विशेष रूप से, AsyncTaskपीछे की संगतता को तोड़े बिना हटाया नहीं जा सकता।
कॉमन्सवेयर


2
@ स्टाइल -7 यह नहीं है।
एपिकपांडाफॉर्क्स

"स्थिर आंतरिक वर्ग" जैसी कोई चीज नहीं है। आपका मतलब है कि एक स्थिर नेस्टेड क्लास।
17

जवाबों:


22
private WeakReference<MyActivity> activityReference;

अच्छी लकीर है कि यह पदावनत है, क्योंकि WeakReference<Context>हमेशा एक हैक था, और एक उचित समाधान नहीं था

अब लोगों को अपने कोड को पवित्र करने का अवसर मिलेगा।


AsyncTask<String, Void, MyPojo> 

इस कोड के आधार पर, Progressवास्तव में जरूरत नहीं है, और एक Stringइनपुट + MyPojoआउटपुट है।

यह वास्तव में AsyncTask के किसी भी उपयोग के बिना पूरा करने के लिए काफी आसान है।

public class TaskRunner {
    private final Executor executor = Executors.newSingleThreadExecutor(); // change according to your requirements
    private final Handler handler = new Handler(Looper.getMainLooper());

    public interface Callback<R> {
        void onComplete(R result);
    }

    public <R> void executeAsync(Callable<R> callable, Callback<R> callback) {
        executor.execute(() -> {
            final R result = callable.call();
            handler.post(() -> {
                callback.onComplete(result);
            });
        });
    }
}

स्ट्रिंग में कैसे पास करें? इस तरह:

class LongRunningTask implements Callable<MyPojo> {
    private final String input;

    public LongRunningTask(String input) {
        this.input = input;
    }

    @Override
    public MyPojo call() {
        // Some long running task
        return myPojo;
    }
}

तथा

// in ViewModel
taskRunner.executeAsync(new LongRunningTask(input), (data) -> {
    // MyActivity activity = activityReference.get();
    // activity.progressBar.setVisibility(View.GONE);
    // populateData(activity, data) ;

    loadingLiveData.setValue(false);
    dataLiveData.setValue(data);
});

// in Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main_activity);

    viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    viewModel.loadingLiveData.observe(this, (loading) -> {
        if(loading) {
            progressBar.setVisibility(View.VISIBLE);
        } else {
            progressBar.setVisibility(View.GONE);
        }
    });

    viewModel.dataLiveData.observe(this, (data) -> {
        populateData(data);
    }); 
}

इस उदाहरण में एकल-थ्रेडेड पूल का उपयोग किया गया है जो DB के लिए अच्छा है (या अनुक्रमित नेटवर्क अनुरोध), लेकिन अगर आप DB के लिए कुछ चाहते हैं या कई अनुरोधों को पढ़ते हैं, तो आप निम्न एक्ज़ीक्यूटर कॉन्फ़िगरेशन पर विचार कर सकते हैं:

private static final Executor THREAD_POOL_EXECUTOR =
        new ThreadPoolExecutor(5, 128, 1,
                TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

मुझे एक त्रुटि मिल रही है executor.post। विधि को हल नहीं कर सकते
क्रिश बी

@ क्रिस को स्पष्ट रूप से इसके execute()बजाय बुलाया जाता हैpost()
एपिकपांडाफॉर्वर्स

क्या आपको पता है कि क्या Contextइस में पास होना ठीक है ? मुझे पता है कि एक Contextमें गुजरना AsyncTaskइसके मुद्दों में से एक था।
क्रि। बी।

आपको अभी भी इसे व्यूमॉडल में बनाए रखने की आवश्यकता है, खंडित, सिंगलटन, या अन्य कुछ भी, जैसा कि आप सामान्य रूप से एंड्रॉइड में कुछ भी नहीं करते हैं।
एपिकपांडाफर्स

1
newSingleThreadExecutorलिखने के लिए बेहतर है, लेकिन आपको THREAD_POOL_EXECUTORडेटाबेस पढ़ने के लिए पोस्ट के अंत में निश्चित रूप से उपयोग करना चाहिए ।
एपिकपांडाफ़ोर्स 1

3

Google जावा के कॉनक्युलर फ्रेमवर्क या कोटलिन कॉरआउट्स का उपयोग करने की सलाह देता है। लेकिन Rxjava के अंत में बहुत अधिक लचीलापन और विशेषताएं हैं, फिर जावा कंसर्टिबिलिटी ने काफी लोकप्रियता हासिल की।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.