মূল কার্যক্রমে অনপোস্টএকসেকিউট () এর ফলাফল কীভাবে পাওয়া যায় কারণ অ্যাসিঙ্কটাস্ক একটি পৃথক শ্রেণি?


361

আমার এই দুটি ক্লাস আছে। আমার মূল ক্রিয়াকলাপ এবং এটি যেটি প্রসারিত করে AsyncTask, এখন আমার মূল ক্রিয়াকলাপে আমাকে এর OnPostExecute()মধ্যে থেকে ফলাফলটি পাওয়া দরকার AsyncTask। আমি কীভাবে আমার মূল ক্রিয়াকলাপে পাস বা ফলাফল পেতে পারি?

এখানে নমুনা কোড।

আমার মূল ক্রিয়াকলাপ।

public class MainActivity extends Activity{

    AasyncTask asyncTask = new AasyncTask();

    @Override
    public void onCreate(Bundle aBundle) {
        super.onCreate(aBundle);            

        //Calling the AsyncTask class to start to execute.  
        asyncTask.execute(a.targetServer); 

        //Creating a TextView.
        TextView displayUI = asyncTask.dataDisplay;
        displayUI = new TextView(this);
        this.setContentView(tTextView); 
    }

}

এটি AsyncTask শ্রেণি

public class AasyncTask extends AsyncTask<String, Void, String> {

TextView dataDisplay; //store the data  
String soapAction = "http://sample.com"; //SOAPAction header line. 
String targetServer = "https://sampletargeturl.com"; //Target Server.

//SOAP Request.
String soapRequest = "<sample XML request>";    



@Override
protected String doInBackground(String... string) {

String responseStorage = null; //storage of the response

try {


    //Uses URL and HttpURLConnection for server connection. 
    URL targetURL = new URL(targetServer);
    HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
    httpCon.setDoOutput(true);
    httpCon.setDoInput(true);
    httpCon.setUseCaches(false); 
    httpCon.setChunkedStreamingMode(0);

    //properties of SOAPAction header
    httpCon.addRequestProperty("SOAPAction", soapAction);
    httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8"); 
    httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
    httpCon.setRequestMethod(HttpPost.METHOD_NAME);


    //sending request to the server.
    OutputStream outputStream = httpCon.getOutputStream(); 
    Writer writer = new OutputStreamWriter(outputStream);
    writer.write(soapRequest);
    writer.flush();
    writer.close();


    //getting the response from the server
    InputStream inputStream = httpCon.getInputStream(); 
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);

    int intResponse = httpCon.getResponseCode();

    while ((intResponse = bufferedReader.read()) != -1) {
        byteArrayBuffer.append(intResponse);
    }

    responseStorage = new String(byteArrayBuffer.toByteArray()); 

    } catch (Exception aException) {
    responseStorage = aException.getMessage(); 
    }
    return responseStorage;
}

protected void onPostExecute(String result) {

    aTextView.setText(result);

}       

}   

আপনি হেলমিবি ব্যাখ্যার মতো একটি ইন্টারফেস তৈরি করতে পারেন বা একটি স্থানীয় সম্প্রচার রিসিভার তৈরি করতে পারেন আপনি এখানে নমুনা সম্প্রচারের রিসিভার বাস্তবায়ন দেখতে পাবেন wiki.workassis.com/android-local-broadcast-receiver
বিকাশ এম

পর্যবেক্ষক নিদর্শন কেন ব্যবহার করবেন না?
JAAAY

উত্তর:


750

সহজ:

  1. interfaceক্লাস তৈরি করুন , যেখানে String outputalচ্ছিক, বা আপনি যে পরিবর্তনগুলি ফিরে আসতে চান তা হতে পারে।

    public interface AsyncResponse {
        void processFinish(String output);
    }
  2. আপনার AsyncTaskক্লাসে যান , এবং AsyncResponseএকটি ক্ষেত্র হিসাবে ইন্টারফেস ঘোষণা করুন :

    public class MyAsyncTask extends AsyncTask<Void, Void, String> {
      public AsyncResponse delegate = null;
    
        @Override
        protected void onPostExecute(String result) {
          delegate.processFinish(result);
        }
     }
  3. আপনার মূল ক্রিয়াকলাপে আপনাকে implementsইন্টারফেস করতে হবেAsyncResponse

    public class MainActivity implements AsyncResponse{
      MyAsyncTask asyncTask =new MyAsyncTask();
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
    
         //this to set delegate/listener back to this class
         asyncTask.delegate = this;
    
         //execute the async task 
         asyncTask.execute();
      }
    
      //this override the implemented method from asyncTask
      @Override
      void processFinish(String output){
         //Here you will receive the result fired from async class 
         //of onPostExecute(result) method.
       }
     }

হালনাগাদ

আমি জানতাম না এটি আপনার অনেকের কাছে এমন প্রিয়। সুতরাং এখানে ব্যবহার করার সহজ এবং সুবিধাজনক উপায় interface

এখনও একই ব্যবহার interface । এফওয়াইআই, আপনি এটি AsyncTaskক্লাসে একত্রিত করতে পারেন ।

মধ্যে AsyncTaskশ্রেণী:

public class MyAsyncTask extends AsyncTask<Void, Void, String> {

  // you may separate this or combined to caller class.
  public interface AsyncResponse {
        void processFinish(String output);
  }

  public AsyncResponse delegate = null;

    public MyAsyncTask(AsyncResponse delegate){
        this.delegate = delegate;
    }

    @Override
    protected void onPostExecute(String result) {
      delegate.processFinish(result);
    }
}

আপনার Activityক্লাসে এই না

public class MainActivity extends Activity {

   MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){

     @Override
     void processFinish(String output){
     //Here you will receive the result fired from async class 
     //of onPostExecute(result) method.
     }
  }).execute();

 }

অথবা, আবার ক্রিয়াকলাপে ইন্টারফেস প্রয়োগ করে

public class MainActivity extends Activity 
    implements AsyncResponse{

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //execute the async task 
        new MyAsyncTask(this).execute();
    }

    //this override the implemented method from AsyncResponse
    @Override
    void processFinish(String output){
        //Here you will receive the result fired from async class 
        //of onPostExecute(result) method.
    }
}

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

টিপ : পরিবর্তনের String output, String responseএবং String resultবিভিন্ন মেলা ধরনের জন্য বিভিন্ন বস্তুর পেতে হবে।


20
সম্পূর্ণরূপে এগুলি সমস্ত লিখেছেন এবং তারপরে আপনার উত্তরটি দেখেছেন :) এখানে সমানভাবে ভাবতে হবে! +1 টি। এছাড়াও এইভাবে একাধিক জিনিস অ্যাসিঙ্কটাস্কের ফলাফল শুনতে পারে!
রোলোক

8
আমি নালপয়েন্টার ব্যতিক্রম পাচ্ছি কারণ প্রতিনিধি বাতিল হয়ে গেছে, দয়া করে এটি পরিষ্কার করুন
রেজিওন

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

13
যারা নাল পয়েন্টার পেয়ে যাচ্ছেন তাদের জন্য আপনার ইন্টারফেসটি আপনার এসিঙ্কটাস্ক ক্লাস কনস্ট্রাক্টারে পাস করুন এবং তারপরে এটি একটি ভেরিয়েবলের জন্য বরাদ্দ করুন এবং তারপরে সেই পরিবর্তনশীলটিতে প্রসেসফিনিশ () কল করুন। রেফারেন্সের জন্য স্বীকৃত অ্যাঞ্জার দেখুন। stackoverflow.com/questions/9963691/…
সানি

2
@ সানি আপনি ঠিক বলেছেন ... এছাড়াও, আমাদের async.delegate = এটির জন্য async অবজেক্টটি শুরু করতে হবে; কাজের জন্য ..
নিনজা_ কোডার

24

কয়েকটি অপশন আছে:

  • AsyncTaskআপনার Activityক্লাসের মধ্যে ক্লাস নীড় । ধরে নিই যে আপনি একাধিক ক্রিয়াকলাপে একই কাজটি ব্যবহার করবেন না, এটি সবচেয়ে সহজ উপায়। আপনার সমস্ত কোড একই থাকে, আপনি কেবলমাত্র বিদ্যমান টাস্ক ক্লাসটিকে আপনার ক্রিয়াকলাপের শ্রেণীর ভিতরে নেস্টেড শ্রেণিতে পরিণত করেন।

    public class MyActivity extends Activity {
        // existing Activity code
        ...
    
        private class MyAsyncTask extends AsyncTask<String, Void, String> {
            // existing AsyncTask code
            ...
        }
    }
  • আপনার জন্য একটি কাস্টম কনস্ট্রাক্টর তৈরি করুন AsyncTaskযা আপনার রেফারেন্স নেয় Activity। আপনি এই জাতীয় কিছু দিয়ে কাজটি তাত্ক্ষণিক করে তুলবেন new MyAsyncTask(this).execute(param1, param2)

    public class MyAsyncTask extends AsyncTask<String, Void, String> {
        private Activity activity;
    
        public MyAsyncTask(Activity activity) {
            this.activity = activity;
        }
    
        // existing AsyncTask code
        ...
    }

দ্বিতীয় বিকল্পে: শ্রেণি না থাকলে কেন একজন কনস্ট্রাক্টর এবং ক্ষেত্রের বেদনা দিয়ে যাবেন static? এর ছায়া গোছানো fieldOrMethodথেকে MyActivityবা কেবল কোনও ব্যবহার করুন MyActivity.this.fieldOrMethod
TWiStErRob

দ্বিতীয় অনুমান @TWiStErRob MyAsyncTaskহয় না ইনার বর্গ।
নিরবতা

1
ওহ, দুঃখিত, private/ protectedশীর্ষ স্তরের শ্রেণির জন্য অনুমোদিত নয়, তাই আমি ভেবেছিলাম এটি অবশ্যই একটি অন-অন্তর্গত staticশ্রেণি হতে হবে ।
TWiStErRob

2
এখানে সাবধানতা অবলম্বন করুন যে এখানে বর্ণিত
মার্ক

2
ক্রিয়াকলাপের রেফারেন্স ধরে রাখা একটি মেমরি ফুটো। কলব্যাক অ্যাপ্রোচ এর চেয়ে অনেক ভাল
ওয়ান ক্রিকেটার

19

আমি অনুভব করেছি নীচের পদ্ধতিটি খুব সহজ।

আমি কলব্যাকের জন্য একটি ইন্টারফেস ঘোষণা করেছি

public interface AsyncResponse {
    void processFinish(Object output);
}

তারপরে সব ধরণের সমান্তরাল অনুরোধগুলির প্রতিক্রিয়া জানাতে অ্যাসিক্রোনাস টাস্ক তৈরি করা হয়েছে

 public class MyAsyncTask extends AsyncTask<Object, Object, Object> {

    public AsyncResponse delegate = null;//Call back interface

    public MyAsyncTask(AsyncResponse asyncResponse) {
        delegate = asyncResponse;//Assigning call back interfacethrough constructor
    }

    @Override
    protected Object doInBackground(Object... params) {

      //My Background tasks are written here

      return {resutl Object}

    }

    @Override
    protected void onPostExecute(Object result) {
        delegate.processFinish(result);
    }

}

তারপরে অ্যাক্টিভিটি ক্লাসে একটি বোতাম ক্লিক করার সময় অ্যাসিক্রোনাস টাস্ক বলা হয়।

public class MainActivity extends Activity{

    @Override
    public void onCreate(Bundle savedInstanceState) {

    Button mbtnPress = (Button) findViewById(R.id.btnPress);

    mbtnPress.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {

                    @Override
                    public void processFinish(Object output) {
                        Log.d("Response From Asynchronous task:", (String) output);

                        mbtnPress.setText((String) output);
                   }
                });

                asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });


            }
        });

    }



}

ধন্যবাদ


17

আপনি আপনার প্রধান শ্রেণিতে এই কোডটি চেষ্টা করতে পারেন। এটি আমার পক্ষে কাজ করেছিল, তবে আমি পদ্ধতিগুলি অন্যভাবে প্রয়োগ করেছি

try {
    String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
} 
catch (ExecutionException | InterruptedException ei) {
    ei.printStackTrace();
}

2
আপনি দয়া করে ব্যাখ্যা করতে পারেন যে এটি কেন তাদের সমস্যার সাথে ওপিকে সহায়তা করবে?
জন ওডম

3
এটি আমাকে সাহায্য করেছিল। আমি @ হেলমিবি থেকে উত্তরটির মতো অন্যভাবে চেষ্টা করেছি কিন্তু আমি কোনও ফল পাই না
নিকু পি

আমার উত্তরের জন্য দুঃখিত। তাকে অ্যাসিঙ্কটাস্ক ক্লাসে কল করতে হবে এবং তারপরে এই কলটিতে একটি পরামিতি স্থাপন করতে হবে। AsyncTask 3 জেনেরিক ধরণের দ্বারা সংজ্ঞায়িত করা হয়েছে: 1 প্যারাম (সার্ভার ডোমেন বা অন্যান্য প্যারাম) 2 অগ্রগতি (বাতিল হতে পারে), 3 ফলাফল result এই সমস্ত ধরণের হতে পারে: JSONObject, বা স্ট্রিং, বা কোনও ডেটা ধরণের। আপনার যখন অ্যাসিঙ্কটাস্ক ক্লাস থাকে তখন আপনাকে ডেটা কোথায় প্রেরণ করতে হবে তা নির্ধারণ করা উচিত। উদাঃ asyncTask.execute (" sampletargeturl.com")। পান () ;
নিকু পি

এই পদ্ধতিটি ব্যবহার করার সময়, আমি লগক্যাটটিতে একটি সতর্কতা পেয়েছিলাম: "আমি / নৃত্য পরিচালক 50 50 ফ্রেম এড়িয়ে গেছেন! অ্যাপ্লিকেশনটি এর মূল থ্রেডে খুব বেশি কাজ করছে।" কিভাবে এটি মোকাবেলা? অ্যাসিঙ্কটাস্ক থেকে প্রত্যাবর্তনের জন্য যখন ইউআই স্থির হয়ে যায়?
হুই ডো

@ নিকুপ আপনি কল করতে ভুলে থাকতে execute()পারেন, আমার উত্তর দেখুন, আমি সেখানে মন্তব্য যুক্ত করেছি। আপনি আমার আপডেট হওয়া উত্তরটি পরীক্ষা করতে চাইতে পারেন। আশাকরি এটা সাহায্য করবে.
হেলমিবি

16

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

কীভাবে এটি সমস্যা সৃষ্টি করতে পারে তা জানতে দয়া করে নীচের স্ক্রিনশটটি দেখুন।

এখানে চিত্র বর্ণনা লিখুন

আপনি দেখতে পাচ্ছেন যে আমরা যদি দৃ strong ় রেফারেন্স AsyncTaskদিয়ে শুরু করেছিলাম তবে আমাদের ডেটা না পাওয়া পর্যন্ত আমাদের / বেঁচে থাকার কোনও গ্যারান্টি নেই , সুতরাং সেই ক্ষেত্রে ব্যবহার করা আরও ভাল হবে এবং এটি মেমরি পরিচালনায় সহায়তা করবে কারণ আমরা কখনই থাকব না আমাদের দৃ reference় রেফারেন্সActivityFragmentWeakReferenceActivity তখনকার বিকৃতির পরে আবর্জনা সংগ্রহের জন্য উপযুক্ত হবে be

কীভাবে দুর্দান্ত WeakReferences ব্যবহার করবেন তা জানতে কোড স্নিপেটটি নীচে দেখুন -

MyTaskInformer.java ইন্টারফেস যা একজন ইনফর্মার হিসাবে কাজ করবে।

public interface MyTaskInformer {

    void onTaskDone(String output);

}

MySmallAsyncTask.javaদীর্ঘ চলমান কাজটি করতে অ্যাসিঙ্কটাস্ক, যা ব্যবহার করবে WeakReference

public class MySmallAsyncTask extends AsyncTask<String, Void, String> {

    // ***** Hold weak reference *****
    private WeakReference<MyTaskInformer> mCallBack;

    public MySmallAsyncTask(MyTaskInformer callback) {
        this.mCallBack = new WeakReference<>(callback);
    }

    @Override
    protected String doInBackground(String... params) {

        // Here do whatever your task is like reading/writing file
        // or read data from your server or any other heavy task

        // Let us suppose here you get response, just return it
        final String output = "Any out, mine is just demo output";

        // Return it from here to post execute
        return output;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        // Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask

        // Make sure your caller is active

        final MyTaskInformer callBack = mCallBack.get();

        if(callBack != null) {
            callBack.onTaskDone(s);
        }
    }
}

MainActivity.javaএই ক্লাসটি এই ক্লাসে এবং এই বাধ্যতামূলক পদ্ধতিতে আমার AsyncTaskবাস্তবায়ন শুরু করতে ব্যবহৃত হয় ।interfaceoverride

public class MainActivity extends Activity implements MyTaskInformer {

    private TextView mMyTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMyTextView = (TextView) findViewById(R.id.tv_text_view);

        // Start your AsyncTask and pass reference of MyTaskInformer in constructor
        new MySmallAsyncTask(this).execute();
    }

    @Override
    public void onTaskDone(String output) {

        // Here you will receive output only if your Activity is alive.
        // no need to add checks like if(!isFinishing())

        mMyTextView.setText(output);
    }
}

2
এটা অসাধারণ! একটি গুরুত্বপূর্ণ বিষয় যা লক্ষ্য করা যায় না।
হ্যাশ

6

আপনার অনক্রিয়েটে ():

`

myTask.execute("url");
String result = "";
try {
      result = myTask.get().toString();
} catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
}catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();

} `


6

আপনি যখন আপনার অ্যাসিঙ্কটাস্ককে কল করবেন তখন আপনি কয়েকটি লাইনে এটি করতে পারেন, পোস্টপেক্সেকিউটকে ওভাররাইড করুন। এখানে আপনার জন্য একটি উদাহরণ:

new AasyncTask()
{
    @Override public void onPostExecute(String result)
    {
       // do whatever you want with result 
    }
}.execute(a.targetServer);

আমি আশা করি এটি আপনাকে সাহায্য করেছে, শুভ কোডিং :)


এটি আমার পক্ষে কাজ করে না। এটি কেবল onPostExecuteপদ্ধতিতে প্রবেশ করে না ।
ফ্রান্সিসকো রোমেরো

4

লোকেরা এটিকে এত কঠিন করে কেন।

এটি যথেষ্ট হওয়া উচিত।

অ্যাসিঙ্ক টাস্কে onPostExecute প্রয়োগ করবেন না, বরং এটি ক্রিয়াকলাপে প্রয়োগ করুন:

public class MainActivity extends Activity 
{

@Override
public void onCreate(Bundle savedInstanceState) {

    //execute the async task 
    MyAsyncTask task = new MyAsyncTask(){
            protected void onPostExecute(String result) {
                //Do your thing
            }       

    }

    task.execute("Param");

}


}

এটি আমার পক্ষে কাজ করে। এটি বোঝার জন্য সহজ এবং সহজ। আমি মনে করি এটি জাভা যা করার জন্য ডিজাইন করেছে তা ব্যবহার করছে। ধন্যবাদ। PS: এটি একটি যুক্ত করা প্রয়োজন @Override?
ওল্ড গিজার

1
না। @ ওভাররাইড কেবল একটি টীকা। সুতরাং আপনি জাভা সংকলককে বলছেন যে আপনি পদ্ধতিটি ওভাররাইড করার ইচ্ছা করছেন এবং যদি আপনি এটি না করছেন তবে অবহিত হন।
বাগডেচি

4

আপনি (বা ওভারলোড ) এর get()পদ্ধতিতে কল করতে পারেন । এই পদ্ধতিটি কাজ শেষ না হওয়া অবধি অবরুদ্ধ হবে , যে সময়ে এটি আপনাকে ফিরিয়ে দেবেAsyncTaskget(long, TimeUnit)AsyncTaskResult

আপনার অ্যাসিঙ্ক টাস্কটি তৈরি / শুরু করার এবং getপদ্ধতিটি কল করার মধ্যে অন্য কাজ করা বুদ্ধিমানের কাজ হবে , অন্যথায় আপনি অ্যাসিঙ্ক কার্যটি খুব দক্ষতার সাথে ব্যবহার করছেন না।


1
ডাউনভোট ভেকজ গেট () মূল থ্রেডকে ব্লক করবে। এটি ব্লক হয়ে থাকলে অ্যাসিঙ্কটাস্ক ব্যবহার করার কোনও কারণ নেই
গ্যাব্রিয়েলবিবি

3

আপনি আপনার নিজের শ্রোতা লিখতে পারেন। এটি হেলমিবির উত্তর হিসাবে একই তবে এটি আরও প্রাকৃতিক দেখায়:

শ্রোতা ইন্টারফেস তৈরি করুন:

public interface myAsyncTaskCompletedListener {
    void onMyAsynTaskCompleted(int responseCode, String result);
}

তারপরে আপনার অ্যাসিক্রোনাস টাস্কটি লিখুন:

public class myAsyncTask extends AsyncTask<String, Void, String> {

    private myAsyncTaskCompletedListener listener;
    private int responseCode = 0;

    public myAsyncTask() {
    }

    public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) {
        this.listener = listener;
        this.responseCode = responseCode;
    }

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


    @Override
    protected String doInBackground(String... params) {
        String result;
        String param = (params.length == 0) ? null : params[0];
        if (param != null) {
            // Do some background jobs, like httprequest...
            return result;
        }
        return null;
    }

    @Override
    protected void onPostExecute(String finalResult) {
        super.onPostExecute(finalResult);
        if (!isCancelled()) {
            if (listener != null) {
                listener.onMyAsynTaskCompleted(responseCode, finalResult);
            }
        }
    }
}

অবশেষে শ্রোতাদের ক্রিয়াকলাপে কার্যকর করুন:

public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener {

    @Override
    public void onMyAsynTaskCompleted(int responseCode, String result) {

        switch (responseCode) {
            case TASK_CODE_ONE: 
                // Do something for CODE_ONE
                break;
            case TASK_CODE_TWO:
                // Do something for CODE_TWO
                break;
            default: 
                // Show some error code
        }        
    }

এবং এভাবেই আপনি asyncTask কল করতে পারেন:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Some other codes...
        new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job");
        // And some another codes...
}

2

হাই আপনি এই জাতীয় কিছু করতে পারেন:

  1. ক্লাস তৈরি করুন যা AsyncTask প্রয়োগ করে

    // TASK 
    public class SomeClass extends AsyncTask<Void, Void, String>>
    {
    
        private OnTaskExecutionFinished _task_finished_event;
    
        public interface OnTaskExecutionFinished
        {
            public void OnTaskFihishedEvent(String Reslut);
        }
    
        public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event)
        {
            if(_event != null)
            {
                this._task_finished_event = _event;
            }
        }
    
        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
    
        }
    
        @Override
        protected String doInBackground(Void... params)
        {
            // do your background task here ...
    
            return "Done!";
        }
    
        @Override
        protected void onPostExecute(String result)
        {
            super.onPostExecute(result);
            if(this._task_finished_event != null)
            {
                this._task_finished_event.OnTaskFihishedEvent(result);
            }
            else
            {
                Log.d("SomeClass", "task_finished even is null");
            }
        }
    }
  2. প্রধান ক্রিয়াকলাপে যুক্ত করুন

    // MAIN ACTIVITY
    public class MyActivity extends ListActivity
    {
       ...
        SomeClass _some_class = new SomeClass();
        _someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished()
        {
        @Override
        public void OnTaskFihishedEvent(String result)
        {
            Toast.makeText(getApplicationContext(),
                    "Phony thread finished: " + result,
                    Toast.LENGTH_SHORT).show();
        }
    
       });
       _some_class.execute();
       ...
     }

1

আপনার ক্রিয়াকলাপ শ্রেণিতে একটি স্থির সদস্য তৈরি করুন। তারপরে মানটি নির্ধারণ করুনonPostExecute

উদাহরণস্বরূপ, যদি আপনার অ্যাসিঙ্কটাস্কের ফলাফলটি একটি স্ট্রিং হয় তবে আপনার ক্রিয়াকলাপে একটি সর্বজনীন স্ট্যাটিক স্ট্রিং তৈরি করুন

public static String dataFromAsyncTask;

তারপরে, onPostExecuteঅ্যাসিঙ্কটাস্ক-এ কেবল আপনার মূল শ্রেণিতে স্ট্যাটিক কল করুন এবং মানটি সেট করুন।

MainActivity.dataFromAsyncTask = "result blah";


1
এই পরিস্থিতিতে স্মৃতি ফাঁস হওয়ার সম্ভাবনাগুলি কী?
এন্ট্রয়েড

0

আমি থ্রেডিং এবং হ্যান্ডলার / বার্তা ব্যবহার করে এটি কাজ করি। নিম্নলিখিত পদক্ষেপগুলি: একটি অগ্রগতি ডায়ালগ ঘোষণা করুন

ProgressDialog loadingdialog;

অপারেশন শেষ হয়ে গেলে ডায়ালগ বন্ধ করতে একটি ফাংশন তৈরি করুন।

   private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        loadingdialog.dismiss();

    }
    };

আপনার নির্বাহের বিশদটি কোড করুন:

 public void startUpload(String filepath) {
    loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true);
    final String _path = filepath;
    new Thread() {
        public void run() {
            try {
                UploadFile(_path, getHostName(), getPortNo());
                handler.sendEmptyMessage(0);

            } catch (Exception e) {
                Log.e("threadmessage", e.getMessage());
            }
        }
    }.start();
}

0

ডেটা ডেলিগেট করতে বা সরবরাহ করতে আপনাকে "প্রোটোকল" ব্যবহার করতে হবেAsynTask

প্রতিনিধি এবং ডেটা উত্স

একটি প্রতিনিধি হ'ল এমন একটি বস্তু যা কোনও প্রোগ্রামে কোনও ইভেন্টের মুখোমুখি হওয়ার সময় বা অন্য বস্তুর পক্ষে সমন্বয় করে কাজ করে। ( অ্যাপল সংজ্ঞা )

প্রোটোকল হ'ল ইন্টারফেস যা কিছু আচরণ নির্ধারণের জন্য কিছু পদ্ধতি নির্ধারণ করে।

এখানে একটি সম্পূর্ণ উদাহরণ !!!


0

এটা চেষ্টা কর:

public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {

    private CallBack callBack;

    public interface CallBack {
        void async( JSONObject jsonResult );
        void sync( JSONObject jsonResult );
        void progress( Integer... status );
        void cancel();
    }

    public SomAsyncTask(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    protected JSONObject doInBackground(String... strings) {

        JSONObject dataJson = null;

        //TODO query, get some dataJson

        if(this.callBack != null)
            this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD

        return dataJson;

    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

        if(this.callBack != null)
            this.callBack.progress(values);// synchronize with MAIN LOOP THREAD

    }

    @Override
    protected void onPostExecute(JSONObject jsonObject) {
        super.onPostExecute(jsonObject);

        if(this.callBack != null)
            this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
    }

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

        if(this.callBack != null)
            this.callBack.cancel();

    }
}

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

public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         final Context _localContext = getContext();
         SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {

                @Override
                public void async(JSONObject jsonResult) {//async thread
                    //some async process, e.g. send data to server...
                }

                @Override
                public void sync(JSONObject jsonResult) {//sync thread
                    //get result...

                    //get some resource of Activity variable...
                    Resources resources = _localContext.getResources();
                }

                @Override
                public void progress(Integer... status) {//sync thread
                    //e.g. change status progress bar...
                }

                @Override
                public void cancel() {

                }

            };

            new SomeAsyncTask( someCallBack )
                                .execute("someParams0", "someParams1", "someParams2");

    }

0

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

অ্যাসিঙ্কটাস্ক বাস্তবায়ন:

public class AsyncDbCall<ExecuteType,ResultType> extends AsyncTask<ExecuteType, Void,  
ResultType>
{
    public interface ExecuteCallback<E, R>
    {
        public R execute(E executeInput);
    }
    public interface PostExecuteCallback<R>
    {
        public void finish(R result);
    }

    private PostExecuteCallback<ResultType> _resultCallback = null;
    private ExecuteCallback<ExecuteType,ResultType> _executeCallback = null;


    AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback, PostExecuteCallback<ResultType> postExecuteCallback)
    {
        _resultCallback = postExecuteCallback;
        _executeCallback = executeCallback;
    }

    AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback)
    {
        _executeCallback = executeCallback;
    }

    @Override
    protected ResultType doInBackground(final ExecuteType... params)
    {
        return  _executeCallback.execute(params[0]);
    }

    @Override
    protected void onPostExecute(ResultType result)
    {
        if(_resultCallback != null)
            _resultCallback.finish(result);
    }
}

একটি কলব্যাক:

 AsyncDbCall.ExecuteCallback<Device, Device> updateDeviceCallback = new 
 AsyncDbCall.ExecuteCallback<Device, Device>()
    {
        @Override
        public Device execute(Device device)
        {
            deviceDao.updateDevice(device);
            return device;
        }
    };

এবং অবশেষে অ্যাসিঙ্ক কার্যটি কার্যকর করা:

 new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);

0

আশা করি আপনি মাধ্যমে হয়েছে এই যদি অনুগ্রহ করে পড়ুন না।

https://developer.android.com/reference/android/os/AsyncTask

ফলাফলের তথ্যের প্রকৃতির উপর নির্ভর করে আপনার মনে করা যায় এমন সেরা সম্ভাব্য বিকল্পটি বেছে নেওয়া উচিত।

ইন্টারফেস ব্যবহার করা এটি দুর্দান্ত পছন্দ

কিছু অন্যান্য বিকল্প হতে পারে ..

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

  • যদি রেজাল্টটি শেয়ারডপ্রেফারেন্স এন্ট্রি হিসাবে সামঞ্জস্য হয় বা মেমোরিতে ফাইল হিসাবে এটি সংরক্ষণ করা ঠিক আছে তবে আপনি এটিকে ব্যাকগ্রাউন্ড টাস্ক থেকেও সংরক্ষণ করতে পারেন এবং ফলাফল পাওয়া গেলে বিজ্ঞপ্তি পেতে অনপস্টেক্সট () পদ্ধতি ব্যবহার করতে পারেন
    স্মৃতি।

  • যদি স্ট্রিংটি যথেষ্ট ছোট হয় এবং কোনও ক্রিয়াকলাপ শুরু করার সাথে এটি ব্যবহার করা হয়। onPostExecute () এর মধ্যে ইন্টেন্ট ( putExtra () ) ব্যবহার করা সম্ভব , তবে মনে রাখবেন যে স্থির প্রসঙ্গটি মোকাবেলা করার পক্ষে নিরাপদ নয়

  • যদি সম্ভব হয়, তবে ফলাফলটি আপনার প্যারামিটার হিসাবে আপনি onPostExecute () পদ্ধতি থেকে একটি স্ট্যাটিক পদ্ধতি কল করতে পারেন

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