java - برمجة الروبوت موضوع مشروع



الروبوت: تمرير إشارة وظيفة إلى أسينكتاسك (2)

أنا جديدة لالروبوت وتستخدم جدا لتطوير الشبكة. في جافاسكريبت عندما تريد تنفيذ مهمة غير متزامنة تقوم بتمرير دالة كوسيطة (رد اتصال):

http.get('www.example.com' , function(response){
   //some code to handle response
});

كنت أتساءل عما إذا كنا نستطيع أن نفعل الشيء نفسه مع الروبوت AsyncTask ، تمرير مرجع وظيفة إلى أسلوب onPostExecute() ، وأنه سيتم تشغيله.

أي اقتراحات ؟

https://ffff65535.com


نعم مفهوم الاستدعاء أيضا موجود كثيرا في جافا. في جافا تقوم بتعريف رد مثل هذا:

public interface TaskListener {
    public void onFinished(String result);
}

واحد غالبا ما عش هذا النوع من التعاريف المستمع داخل AsyncTask مثل هذا:

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

    public interface TaskListener {
        public void onFinished(String result);
    }

    ...
}

وتنفيذ كامل من الاستدعاء في AsyncTask تبدو مثل هذا:

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

    public interface TaskListener {
        public void onFinished(String result);
    }

    // This is the reference to the associated listener
    private final TaskListener taskListener;

    public ExampleTask(TaskListener listener) {
        // The listener reference is passed in through the constructor
        this.taskListener = listener;
    }

    @Override
    protected String doInBackground(Void... params) {
        return doSomething();
    }

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

        // In onPostExecute we check if the listener is valid
        if(this.taskListener != null) {

            // And if it is we call the callback function on it.
            this.taskListener.onFinished(result);
        }
    }
}

يتم استدعاء onPostExecute() بمجرد انتهاء مهمة الخلفية. يمكنك استخدام كل شيء مثل هذا:

ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
});

task.execute();

أو يمكنك تحديد TaskListener بشكل منفصل تماما مثل هذا:

ExampleTask.TaskListener listener = new ExampleTask.TaskListener() {
    @Override
    public void onFinished(String result) {
        // Do Something after the task has finished
    }
};

ExampleTask task = new ExampleTask(listener);    
task.execute();

أو يمكنك TaskListener مثل هذا:

public class ExampleTaskListener implements TaskListener {

    @Override
    public void onFinished(String result) {

    }
}

ومن ثم استخدامه مثل هذا:

ExampleTask task = new ExampleTask(new ExampleTaskListener());    
task.execute();

يمكنك بالطبع تجاوز فقط على طريقة onPostExecute() من AsyncTask ، ولكن هذا غير مستحسن، وفي معظم الحالات في الواقع ممارسة سيئة للغاية. على سبيل المثال، يمكنك إجراء ذلك:

ExampleTask task = new ExampleTask() {
    @Override
    public void onPostExecute(String result) {
        super.onPostExecute(result);

        // Your code goes here
    }
};

هذا سيعمل فقط فضلا عن تنفيذ أعلاه مع واجهة مستمع منفصلة، ​​ولكن هناك بعض المشاكل مع هذا:

أولا وقبل كل شيء يمكنك فعلا كسر ExampleTask معا. كل ذلك يأتي إلى super.onPostExecute() أعلاه. إذا كنت المطور تجاوز على onPostExecute() مثل أعلاه ونسيان تضمين المكالمة الفائقة أو ببساطة حذفه لأي سبب من الأسباب التي لن يتم استدعاء الأسلوب onPostExecute() الأصلي onPostExecute() في ExampleTask بعد الآن. على سبيل المثال تنفيذ المستمع بأكمله مع TaskListener فجأة لم تعد تعمل منذ الآن يتم تنفيذ المكالمة إلى الاستدعاء في على onPostExecute() . يمكنك أيضا كسر TaskListener في العديد من الطرق الأخرى عن طريق تدري أو التأثير عن غير قصد على حالة ExampleTask حتى أنها لن تعمل بعد الآن.

إذا نظرتم إلى ما يحدث في الواقع عند تجاوز طريقة مثل هذا من يصبح أكثر وضوحا ما يجري. بواسطة تجاوز onPostExecute() تقوم بإنشاء فئة فرعية جديدة من ExampleTask . سيكون نفس الشيء بالضبط مثل القيام بذلك:

public class AnotherExampleTask extends ExampleTask {

    @Override
    public void onPostExecute(String result) {
        super.onPostExecute(result);

        // Your code goes here
    }
}

كل هذا مخفي فقط وراء ميزة اللغة تسمى الطبقات المجهولة. فجأة تجاوز طريقة مثل هذا لا يبدو نظيفة جدا وسريعة بعد الآن يفعل ذلك؟

لتلخيص:

  • يؤدي تجاوز طريقة من هذا القبيل إلى إنشاء فئة فرعية جديدة. كنت لا مجرد إضافة رد، كنت تقوم بتعديل كيف يعمل هذا الفصل، ويمكن كسر تدري يا أشياء كثيرة.
  • أخطاء التصحيح مثل هذا يمكن أن يكون أكثر بكثير من مجرد ألم في **. لأن فجأة ExampleTask يمكن رمي Exceptions أو ببساطة لا تعمل بعد الآن لأي سبب واضح، لأنك لم تعدل في الواقع ExampleTask .
  • كل فئة لديها لتقديم تطبيقات المستمع في الأماكن التي يكون مناسبا والمقصود. بالتأكيد يمكنك فقط إضافتها في وقت لاحق عن طريق تجاوز على onPostExecute() ولكن هذا هو دائما خطير جدا. حتىflup مع سمعته 13K قد نسيت لتشمل super.onPostExecute() استدعاء في جوابه، تخيل ما بعض الآخرين لا كما شهدت المطور قد تفعل!
  • القليل من التجريد لا تؤذي أي شخص. كتابة مستمعين معينين قد يكون أكثر قليلا رمز، لكنه حل أفضل بكثير. سوف رمز يكون أنظف، وأكثر قابلية للقراءة وأكثر من ذلك بكثير الحفاظ عليها. استخدام اختصارات مثل تجاوز على onPostExecute() يضحي أساسا جودة رمز للراحة قليلا. هذه ليست فكرة جيدة أبدا سوف يسبب مشاكل فقط على المدى الطويل.

في جافا، تكون الوظائف أقل من مواطنة من الدرجة الأولى من جافاسكريبت. يوفر أسينكتاسك رد كطريقة في الفئة، التي يجب تجاوز.

انظر جعل طلب هتب مع الروبوت لفئة فرعية من أسينكتاسك مع تنفيذ دوينباكغروند الذي يجعل طلب ويب.

إذا كنت تريد أن تفعل طلبات هتب متعددة مع استدعاءات مختلفة، يمكنك تجاوز ريكستاسك وتنفيذ على بوستكسكوت مع تطبيقات الاستدعاء مختلفة. يمكنك استخدام فئة مجهولة لمحاكاة الإغلاق يستخدم استدعاء جافا سكريبت عادة:

new RequestTask(){
    @Override
    public void onPostExecute(String result) {
        // Implementation has read only access to 
        // final variables in calling scope. 
    }
}.execute("http://.com");

كما يظهر زافير، يمكنك أيضا إنشاء واجهة كاملة للمستمع. هذا يبدو مفيدا فقط لي إذا كنت ترغب في تنفيذ اثنين من الافتراضي على وظائف بوستكسكيوت واختيار واحد من هذه التطبيقات الافتراضية لمكالمة معينة.





android-asynctask