मुख्य गतिविधि पर OnPostExecute () का परिणाम कैसे प्राप्त करें क्योंकि AsyncTask एक अलग वर्ग है?


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);

}       

}   

आप समझाए गए हेल्मिबी जैसा एक इंटरफ़ेस बना सकते हैं या आप एक स्थानीय प्रसारण रिसीवर बना सकते हैं। आप यहाँ पर नमूना प्रसारण reciver कार्यान्वयन देख सकते हैं wiki.workassis.com/android-local-broadcast-receiver
बीकेश एम।

ऑब्जर्वर पैटर्न का उपयोग क्यों नहीं करते?
JAAAY

जवाबों:


750

आसान:

  1. interfaceक्लास बनाएं , जहां String outputवैकल्पिक हो, या जो भी चर आप वापस करना चाहते हैं।

    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। FYI करें, आप इसे 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.
    }
}

जैसा कि आप ऊपर 2 समाधान देख सकते हैं, पहला और तीसरा एक, इसे विधि बनाने की आवश्यकता है processFinish, दूसरा एक, विधि कॉलर पैरामीटर के अंदर है। तीसरा अधिक साफ-सुथरा है क्योंकि कोई नस्टेड अनाम वर्ग नहीं है। उम्मीद है की यह मदद करेगा

युक्ति : बदलें String output, String responseऔर String resultअलग-अलग मिलान प्रकार के आदेश विभिन्न वस्तुओं प्राप्त करने के लिए।


20
पूरी तरह से यह सब लिखा है और फिर अपना जवाब देखा :) यहाँ एक जैसा सोच रहा है! +1। इस तरह से कई चीजें AsyncTask के परिणामों को सुन सकती हैं!
रोलोक

8
मुझे nullpointer अपवाद मिल रहा है क्योंकि प्रतिनिधि अशक्त करने के लिए तैयार है, कृपया इसे
स्पष्ट करें

2
.Net डेवलपर्स के लिए बस एक नोट, कोई इसे प्राप्त करने के लिए AutoResetEvents का उपयोग कर सकता है और ऑटोरेसेटेवेंट्स के लिए एक जावा कार्यान्वयन भी है लेकिन यह बहुत साफ है। वैसे, क्या ProcessFinish धागा सुरक्षित है?
सिल्वर

13
उन सभी के लिए जो शून्य पॉइंटर प्राप्त कर रहे हैं, अपने इंटरफ़ेस को आपके asyncTask क्लास कंस्ट्रक्टर के पास भेजते हैं और फिर उसे एक वेरिएबल पर असाइन करते हैं और फिर उस वेरिएबल पर प्रोसेसफिनिश () कॉल करते हैं। संदर्भ के लिए देखें asnwer स्वीकार किए जाते हैं। stackoverflow.com/questions/9963691/…
सनी

2
@ आप सही हैं ... भी, हमें async.delegate = के लिए async ऑब्जेक्ट को इनिशियलाइज़ करना है; काम करने के लिए ..
Ninja_Coder

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 दूसरी मान्यता यह नहींMyAsyncTask है कि एक आंतरिक वर्ग है।
शांत

1
ओह, क्षमा करें, private/ protectedशीर्ष स्तर की कक्षाओं के लिए अनुमति नहीं है, इसलिए मैंने सोचा कि यह एक गैर staticआंतरिक वर्ग होना चाहिए ।
ट्वीस्टरेब

2
बस सावधान रहें कि इनर क्लास AsyncTask मेमोरी लीक्स का एक स्रोत हो सकता है जैसा कि यहां बताया गया है। garena.github.io/blog/2014/09/10/android-memory-leaks
Mark Pazon

2
एक गतिविधि संदर्भ पर पकड़ भी एक स्मृति रिसाव है। कॉलबैक का दृष्टिकोण इससे कहीं बेहतर है
OneCricketeer

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
क्या आप कृपया बता सकते हैं कि इससे ओपी को उनके मुद्दे पर मदद मिलेगी?
जॉन Odom

3
इससे मुझे मदद मिली। मैंने @HelmiB से उत्तर की तरह दूसरे तरीके से कोशिश की, लेकिन मुझे कोई परिणाम नहीं मिला
पी

ठीक है मेरे जवाब के लिए क्षमा करें। उसे AsyncTask वर्ग को कॉल करने की आवश्यकता है, और फिर इस कॉल के लिए एक पैरामीटर लगाने के लिए। AsyncTask को 3 सामान्य प्रकारों से परिभाषित किया गया है: 1 params (सर्वर डोमेन या अन्य परम) 2 प्रगति (शून्य हो सकती है), 3 परिणाम। ये सभी प्रकार हो सकते हैं: JSONObject, या स्ट्रिंग्स, या कोई डेटा प्रकार। जब आपके पास एक AsyncTask वर्ग होता है, तो आपको यह परिभाषित करना चाहिए कि डेटा कहाँ भेजना है। ex: asyncTask.execute (" sampletargeturl.com")। get () ;
निकु पी

इस पद्धति का उपयोग करते समय, मुझे Logcat पर एक चेतावनी मिली: "I / कोरियोग्राफर ipped 50 फ्रेम छोड़ दिया गया! आवेदन अपने मुख्य धागे पर बहुत अधिक काम कर सकता है।" इससे कैसे निपटें? क्या AsyncTask से लौटने पर UI फ्रीज़ हो जाता है?
हू डू डू

@NicuP आप कॉल करना भूल गए execute(), मेरा उत्तर देखें, मैंने वहाँ टिप्पणी जोड़ दी है। आप मेरे अपडेट किए गए उत्तर की जांच करना चाहते हैं। उम्मीद है की यह मदद करेगा।
हेल्मीबी

16

यह उत्तर देर से हो सकता है लेकिन मैं कुछ बातों का उल्लेख करना चाहूंगा जब आपके Activityआश्रित होंगे AsyncTask। जो आपको क्रैश और मेमोरी मैनेजमेंट को रोकने में मदद करेगा। जैसा कि ऊपर दिए गए उत्तरों में पहले ही बताया गया है interface, हम उन्हें कॉलबैक भी कहते हैं। वे एक मुखबिर के रूप में काम करेंगे, लेकिन कभी भी मजबूत संदर्भ न भेजें Activityया interfaceहमेशा उन मामलों में कमजोर संदर्भ का उपयोग करें ।

कृपया स्क्रीनशॉट के नीचे देखें कि यह कैसे समस्या पैदा कर सकता है।

यहां छवि विवरण दर्ज करें

जैसा कि आप देख सकते हैं कि अगर हमने AsyncTaskएक मजबूत संदर्भ के साथ शुरुआत की है , तो इस बात की कोई गारंटी नहीं है कि डेटा मिलने तक हमारा Activity/ Fragmentजीवित रहेगा, इसलिए WeakReferenceउन मामलों में उपयोग करना बेहतर होगा और यह स्मृति प्रबंधन में भी मदद करेगा क्योंकि हम कभी भी पकड़ में नहीं आएंगे हमारे मजबूत संदर्भActivity तो इसके विरूपण के बाद कचरा संग्रहण के लिए पात्र होंगे।

नीचे दिए गए कोड स्निपेट के बारे में जानने के लिए जानिए कि भयानक WeakReference का उपयोग कैसे किया जाता है -

MyTaskInformer.java इंटरफ़ेस जो एक मुखबिर के रूप में काम करेगा।

public interface MyTaskInformer {

    void onTaskDone(String output);

}

MySmallAsyncTask.javaलंबे समय तक चलने वाले कार्य करने के लिए AsyncTask, जो उपयोग करेगा 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

अपने Oncreate में ():

`

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

जब आप अपने AsyncTask को कॉल करते हैं, तो आप इसे कुछ पंक्तियों में कर सकते हैं, बस onPostExecute को ओवरराइड करें। यहाँ आपके लिए एक उदाहरण है:

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

मुझे आशा है कि यह आपकी मदद करेगा, खुश कोडिंग :)


यह मेरे लिए काम नहीं करता है। यह सिर्फ onPostExecuteविधि में प्रवेश नहीं करता है ।
फ्रांसिस्को रोमेरो

4

लोग इसे इतना कठिन क्यों बनाते हैं।

यह पर्याप्त होना चाहिए।

Async कार्य पर 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");

}


}

यह मेरे लिए काम करता है। यह सरल और समझने में आसान है। मुझे लगता है कि यह जावा का उपयोग करने के लिए डिज़ाइन किया गया है। धन्यवाद। पुनश्च: क्या यह जोड़ना आवश्यक है @Override?
पुराना गीजर

1
नहीं @Override सिर्फ एक एनोटेशन है। तो आप जावा कंपाइलर को बता रहे हैं कि आप इस विधि को ओवरराइड करने का इरादा कर रहे हैं और यदि आप ऐसा नहीं कर रहे हैं तो सूचित करें।
बगदादी 10

4

आप (या अतिभारित ) की get()विधि को कॉल कर सकते हैं । यह विधि तब तक ब्लॉक रहेगी, जब तक कि उसने अपना काम पूरा नहीं कर लिया है, इस बिंदु पर यह आपको वापस लौटा देगाAsyncTaskget(long, TimeUnit)AsyncTaskResult

यह समझदारी होगी कि आप अपने async कार्य के निर्माण / प्रारंभ के बीच अन्य कार्य कर रहे हैं और getविधि को कॉल कर रहे हैं, अन्यथा आप async कार्य को बहुत कुशलता से उपयोग नहीं कर रहे हैं।


1
डाउनवोटेड वॉकआउट मिलता है () मुख्य धागे को अवरुद्ध करेगा। AsyncTask का उपयोग करने का कोई कारण नहीं है अगर यह ब्लॉक करेगा
गेब्रियलबी

3

आप अपने खुद के श्रोता लिख ​​सकते हैं। यह HelmiB के उत्तर के समान है लेकिन अधिक प्राकृतिक दिखता है:

श्रोता इंटरफ़ेस बनाएँ:

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

उदाहरण के लिए, यदि आपका AsyncTask का परिणाम एक स्ट्रिंग है, तो अपनी गतिविधि में एक सार्वजनिक स्थैतिक स्ट्रिंग बनाएं

public static String dataFromAsyncTask;

फिर, onPostExecuteAsyncTask में, बस अपने मुख्य वर्ग को एक स्थिर कॉल करें और मूल्य निर्धारित करें।

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

डेलिगेट्स और डेटा स्रोत

एक प्रतिनिधि एक वस्तु है जो किसी वस्तु की ओर से या किसी अन्य वस्तु के साथ समन्वय में कार्य करता है, जब वह वस्तु किसी कार्यक्रम में किसी घटना का सामना करती है। ( Apple परिभाषा )

प्रोटोकॉल कुछ इंटरफेस को परिभाषित करने के लिए कुछ तरीकों को परिभाषित करने वाले इंटरफेस हैं।

यहाँ एक पूर्ण उदाहरण है !!!


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

संभवत: थोड़ा आगे जा रहा था लेकिन मैंने निष्पादन कोड और परिणामों दोनों के लिए कॉल बैक प्रदान किए। स्पष्ट रूप से धागा सुरक्षा के लिए आप सावधान रहना चाहते हैं कि आप अपने निष्पादन कॉलबैक में क्या एक्सेस करते हैं।

AsyncTask कार्यान्वयन:

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;
        }
    };

और अंत में async कार्य का निष्पादन:

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

0

आशा है कि आप इस के माध्यम से , अगर नहीं तो कृपया पढ़ें।

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

परिणाम डेटा की प्रकृति के आधार पर, आपको सबसे अच्छा संभव विकल्प चुनना चाहिए जिसे आप सोच सकते हैं।

यह एक इंटरफ़ेस का उपयोग करने के लिए एक शानदार विकल्प है

कुछ अन्य विकल्प होंगे ।।

  • यदि AsyncTask वर्ग को उस वर्ग के अंदर परिभाषित किया गया है जिसका आप परिणाम का उपयोग करना चाहते हैं। एक स्थिर वैश्विक चर का उपयोग करें या प्राप्त करें () , बाहरी वर्ग ( यदि आवश्यक हो तो अस्थिर चर ) से इसका उपयोग करें । लेकिन AsyncTask प्रगति के बारे में पता होना चाहिए या कम से कम यह सुनिश्चित करना चाहिए कि यह कार्य पूरा कर चुका है और परिणाम वैश्विक चर / प्राप्त () विधि के माध्यम से उपलब्ध है। आप मतदान का उपयोग कर सकते हैं , onProgressUpdate (प्रगति ...) , तुल्यकालन या इंटरफेस (जो आपके लिए सबसे अच्छा सूट करते हैं)

  • यदि परिणाम एक साझा प्रविष्टि प्रविष्टि के लिए संगत है या यह मेमोरी में एक फ़ाइल के रूप में सहेजा जाना ठीक है, तो आप इसे पृष्ठभूमि कार्य से भी बचा सकते हैं और परिणाम उपलब्ध होने पर अधिसूचित होने के लिए onPostExecute () विधि
    का उपयोग कर सकते हैं। यादाश्त।

  • यदि स्ट्रिंग काफी छोटा है, और एक गतिविधि की शुरुआत के साथ उपयोग किया जाना है। इसका इस्तेमाल करने के लिए संभव है उद्देश्य ( putExtra () ) के भीतर onPostExecute () , लेकिन याद रखें कि स्थिर संदर्भों कि सुरक्षित नहीं हैं से निपटने के लिए।

  • यदि संभव हो, तो आप अपने पैरामीटर होने के साथ onPostExecute () विधि से एक स्थिर विधि को कॉल कर सकते हैं

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