অ্যান্ড্রয়েড - অ্যাসিঙ্কটাস্কের জন্য একটি টাইমআউট সেট করছেন?


125

আমার একটি AsyncTaskক্লাস রয়েছে যা আমি কার্যকর করি যা একটি ওয়েবসাইট থেকে ডেটার একটি বৃহত তালিকা ডাউনলোড করে।

ব্যবহারের সময় শেষ ব্যবহারকারীর খুব ধীর গতির বা দাগযুক্ত ডেটা সংযোগ রয়েছে সে ক্ষেত্রে আমি AsyncTaskসময়কালের পরে সময়সীমাটি তৈরি করতে চাই । আমার এটি সম্পর্কে প্রথম পদ্ধতির মত:

MyDownloader downloader = new MyDownloader();
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
  @Override
  public void run() {
      if ( downloader.getStatus() == AsyncTask.Status.RUNNING )
          downloader.cancel(true);
  }
}, 30000 );

শুরু করার পরে AsyncTask, একটি নতুন হ্যান্ডলার শুরু হয় যা AsyncTaskএটি চলমান থাকলে 30 সেকেন্ডের পরে বাতিল হয়ে যায়।

এই একটি ভাল পন্থা? বা এমন কিছু তৈরি করা আছে যা AsyncTaskএই উদ্দেশ্যে আরও উপযুক্ত?


18
বেশ কয়েকটি ভিন্ন পদ্ধতির চেষ্টা করার পরে, আমি এই সিদ্ধান্তে পৌঁছেছি যে আপনার প্রশ্নের উত্তর অবশ্যই গ্রহণযোগ্য হওয়া উচিত।
জনয়ে

এই প্রশ্নের জন্য আমি সত্যিই একই সমস্যার মধ্যে পড়েছি এবং আপনার কোডের
টুকরটি

1
আপনার প্রশ্নটি নিজেই একটি ভাল উত্তর +50 :)
কার্তিক কোলানজি

উত্তর:


44

হ্যাঁ, রয়েছে অ্যাসিঙ্কটাস্ক.গেট ()

myDownloader.get(30000, TimeUnit.MILLISECONDS);

নোট করুন যে এটিকে মূল থ্রেডে (একো। ইউআই থ্রেড) কল করে মৃত্যুদন্ড কার্যকর হবে, আপনার সম্ভবত এটি আলাদা থ্রেডে কল করা দরকার।


9
দেখে মনে হচ্ছে এটি অ্যাসিঙ্কটাস্ক ব্যবহারের উদ্দেশ্যটি হারাতে শুরু করে যদি এই টাইমআউট পদ্ধতিটি মূল ইউআই থ্রেডে চালিত হয় ... তবে কেন handlerআমি আমার প্রশ্নে বর্ণিত পদ্ধতিটি ব্যবহার করব না ? অনেক বেশি সরল মনে হচ্ছে কারণ হ্যান্ডলারের চালনযোগ্য চালানোর জন্য অপেক্ষা করার সময় ইউআই থ্রেড হিমশীতল হয় না ...
জ্যাক উইলসন

ঠিক আছে ধন্যবাদ, আমি ঠিক করতে পারি না যে এটি করার কোনও সঠিক উপায় আছে কিনা।
জ্যাক উইলসন 21

3
আপনি কেন অন্য থ্রেডে () কে কল করবেন তা আমি বুঝতে পারি না। এটি অদ্ভুত দেখাচ্ছে কারণ অ্যাসিঙ্কটাস্ক নিজেই এক ধরণের থ্রেড। আমি মনে করি জাকোবুদ এর সমাধান আরও ঠিক আছে।
পান্নাঘিউ

আমি মনে করি। আপনার ক্ষেত্রে এটি সময়সীমা হিসাবে কাজ করে যা একটি পরিস্থিতিতে পরিস্থিতি। এজন্য আপনাকে প্রধান ইউআই ব্লকিং এড়ানোর জন্য হ্যান্ডলার থেকে বা অন্য থ্রেড থেকে .get () কল করতে হবে
কনস্টান্টাইন সামোইলেনকো

2
আমি জানি এটি বহু বছর পরে, তবে এটি এখনও অ্যান্ড্রয়েডের মধ্যে অন্তর্নির্মিত নয় তাই আমি একটি সমর্থন শ্রেণি তৈরি করেছিলাম। আমি আশা করি এটি কাউকে সাহায্য করবে। gist.github.com/scottTomaszewski/…
স্কট

20

ক্ষেত্রে, আপনার ডাউনলোডারটি কোনও ইউআরএল সংযোগের জন্য ভিত্তি করে, আপনার অনেকগুলি পরামিতি রয়েছে যা আপনাকে জটিল কোড ছাড়াই টাইমআউট নির্ধারণ করতে সহায়তা করতে পারে:

  HttpURLConnection urlc = (HttpURLConnection) url.openConnection();

  urlc.setConnectTimeout(15000);

  urlc.setReadTimeout(15000);

আপনি যদি এই কোডটি আপনার অ্যাসিঙ্ক কার্যটিতে নিয়ে আসেন তবে এটি ঠিক আছে।

'রিড টাইমআউট' হ'ল স্থানান্তরের পাশাপাশি একটি খারাপ নেটওয়ার্ক পরীক্ষা করা।

'সংযোগের সময়সীমা' কেবলমাত্র সার্ভারটি শেষ কিনা তা পরীক্ষা করার জন্য ডাকা হয়।


1
আমি একমত এই পদ্ধতির ব্যবহারটি সহজ এবং সময়সীমাটি শেষ হওয়ার পরে এটি সংযোগটি বন্ধ করে দেয়। AsyncTask.get () পদ্ধতির ব্যবহার করে আপনাকে কেবল অবহিত করা হবে যে সময় সীমাটি পৌঁছেছে, তবে ডাউনলোডটি এখনও প্রক্রিয়াধীন রয়েছে এবং পরবর্তী সময়ে সম্পূর্ণ হতে পারে - কোডটিতে আরও জটিলতা সৃষ্টি করে। ধন্যবাদ।
ধাঁধা

খুব মন্থর ইন্টারনেট সংযোগে প্রচুর থ্রেড ব্যবহার করার সময় এটি যথেষ্ট নয় দয়া করে সচেতন হন। আরও তথ্য: leakfromjavaheap.blogspot.nl/2013/12/… এবং thushw.blogspot.nl/2010/10/…
কাপাইটাইন উইটবার্ড

20

অনপ্রি এক্সেকিউট () পদ্ধতিতে অ্যাসিঙ্কটাস্কের জন্য বর্ধিত শ্রেণীর পাশে কাউন্টডাউনটাইমার ক্লাস ব্যবহার করুন:

প্রধান সুবিধা, Async পর্যবেক্ষণ শ্রেণিতে অভ্যন্তরীণভাবে সম্পন্ন হয়েছিল।

public class YouExtendedClass extends AsyncTask<String,Integer,String> {
...
public YouExtendedClass asyncObject;   // as CountDownTimer has similar method -> to prevent shadowing
...
@Override
protected void onPreExecute() {
    asyncObject = this;
    new CountDownTimer(7000, 7000) {
        public void onTick(long millisUntilFinished) {
            // You can monitor the progress here as well by changing the onTick() time
        }
        public void onFinish() {
            // stop async task if not in progress
            if (asyncObject.getStatus() == AsyncTask.Status.RUNNING) {
                asyncObject.cancel(false);
                // Add any specific task you wish to do as your extended class variable works here as well.
            }
        }
    }.start();
...

কাউন্টডাউনটাইমার (7000, 7000) -> কাউন্টডাউনটাইমারের (7000, 1000) উদাহরণস্বরূপ এবং এটি ফিনিশ () কল করার আগে 6 বার অনটিক () কল করবে। আপনি যদি কিছু মনিটরিং যুক্ত করতে চান তবে এটি ভাল।

এই পৃষ্ঠায় আমি পেয়েছি সমস্ত ভাল পরামর্শের জন্য ধন্যবাদ :-)


2

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

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


0
         Context mContext;

         @Override
         protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
                                    mContext = this;

            //async task
            final RunTask tsk = new RunTask (); 
            tsk.execute();

            //setting timeout thread for async task
            Thread thread1 = new Thread(){
            public void run(){
                try {
                    tsk.get(30000, TimeUnit.MILLISECONDS);  //set time in milisecond(in this timeout is 30 seconds

                } catch (Exception e) {
                    tsk.cancel(true);                           
                    ((Activity) mContext).runOnUiThread(new Runnable()
                    {
                         @SuppressLint("ShowToast")
                        public void run()
                         {
                            Toast.makeText(mContext, "Time Out.", Toast.LENGTH_LONG).show();
                            finish(); //will close the current activity comment if you don't want to close current activity.                                
                         }
                    });
                }
            }
        };
        thread1.start();

         }

2
পাশাপাশি কিছু ব্যাখ্যা যুক্ত করার কথা বিবেচনা করুন
সাইফ আসিফ

0

বাতিলকরণকে আরও শক্তিশালী করার জন্য আপনি আরও একটি শর্ত রাখতে পারেন। যেমন,

 if (downloader.getStatus() == AsyncTask.Status.RUNNING || downloader.getStatus() == AsyncTask.Status.PENDING)
     downloader.cancel(true);

0

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

public void loadData()
    {
        final Load loadUserList=new Load();
        loadUserList.execute();
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (loadUserList.getStatus() == AsyncTask.Status.RUNNING) {
                    loadUserList.cancel(true);
                    pDialog.cancel();
                    new AlertDialog.Builder(UserList.this)
                            .setTitle("Error..!")
                            .setMessage("Sorry you dont have proper net connectivity..!\nCheck your internet settings or retry.")
                            .setCancelable(false)
                            .setPositiveButton("Retry", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    loadData();
                                }
                            })
                            .setNegativeButton("Exit", new DialogInterface.OnClickListener() {
                                @Override


                      public void onClick(DialogInterface dialogInterface, int i) {
                                System.exit(0);
                            }
                        })
                        .show();
            }
        }
    }, LOADING_TIMEOUT);
    return;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.