Есть ли способ объединить все AsyncTasks в один объект службы? [Дубликат]

Прокрутка страницы до ближайшей точки, упомянутой в исключении, сделала трюк для меня. Ниже приведен фрагмент кода:

$wd_host = 'http://localhost:4444/wd/hub';
$capabilities =
    [
        \WebDriverCapabilityType::BROWSER_NAME => 'chrome',
        \WebDriverCapabilityType::PROXY => [
            'proxyType' => 'manual',
            'httpProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
            'sslProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
            'noProxy' =>  PROXY_EXCEPTION // to run locally
        ],
    ];
$webDriver = \RemoteWebDriver::create($wd_host, $capabilities, 250000, 250000);
...........
...........
// Wait for 3 seconds
$webDriver->wait(3);
// Scrolls the page vertically by 70 pixels 
$webDriver->executeScript("window.scrollTo(0, 70);");

ПРИМЕЧАНИЕ. Я использую Facebook php webdriver

288
задан God 7 April 2016 в 07:57
поделиться

13 ответов

Я понял, что подход ниже очень прост.

Я объявил интерфейс для обратного вызова

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.." });


            }
        });

    }



}

Спасибо

637
ответ дан cricket_007 27 August 2018 в 19:27
поделиться

Почему люди делают это так сложно.

Этого должно быть достаточно.

Не реализуйте onPostExecute в задаче async, скорее реализуйте его в Activity:

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

}


}
4
ответ дан bugdayci 27 August 2018 в 19:27
поделиться

Вы можете написать свой собственный слушатель. Это же, что и ответ 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
ответ дан Community 27 August 2018 в 19:27
поделиться

Вам необходимо использовать «протоколы» для делегирования или предоставления данных в AsynTask.

Делегаты и источники данных

Делегат - это объект, который действует от имени, или в координации с другим объектом, когда этот объект встречает событие в программе. ( Определение Apple )

протоколы - это интерфейсы, которые определяют некоторые методы делегирования некоторых действий.

Вот полный пример !!!

0
ответ дан IgniteCoders 27 August 2018 в 19:27
поделиться

Создайте статический член в своем классе Activity. Затем назначьте значение во время onPostExecute

Например, если результат вашей AsyncTask является строкой, создайте в своей активности статическую строку public

public static String dataFromAsyncTask;

Затем в onPostExecute AsyncTask просто сделайте статический вызов вашему основному классу и установите значение.

MainActivity.dataFromAsyncTask = "result blah";

1
ответ дан mrres1 27 August 2018 в 19:27
поделиться

Вы можете вызвать метод get() в AsyncTask (или перегруженный get(long, TimeUnit) ). Этот метод будет блокироваться до тех пор, пока AsyncTask не завершит свою работу, и в этот момент он вернет вам Result.

Было бы разумно выполнять другую работу между созданием / запуском вашего асинхронного задание и вызов метода get, в противном случае вы не используете задачу async очень эффективно.

2
ответ дан nicholas.hauschild 27 August 2018 в 19:27
поделиться

Вы можете попробовать этот код в своем основном классе. Это сработало для меня, но я использовал методы другим способом

try {
    String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
} 
catch (ExecutionException | InterruptedException ei) {
    ei.printStackTrace();
}
13
ответ дан Nicu P 27 August 2018 в 19:27
поделиться

Привет, вы можете сделать что-то вроде этого:

  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();
       ...
     }
    
2
ответ дан Oleg Karbushev 27 August 2018 в 19:27
поделиться

Этот ответ может быть запоздалым, но я хотел бы упомянуть несколько вещей, когда ваш Activity зависит от AsyncTask. Это поможет вам предотвратить сбои и управление памятью. Как уже упоминалось в приведенных выше ответах, переходите к interface, мы также говорим, что они обратные вызовы. Они будут работать как информатор, но никогда не будут отправлять ссылки Activity или interface всегда использовать слабую ссылку в этих случаях.

Пожалуйста, обратитесь к скриншоту ниже, чтобы узнать, как это может вызвать проблемы.

Как вы можете видеть, начали ли мы AsyncTask с сильной ссылки, тогда нет гарантии, что наш Activity / Fragment будет до тех пор, пока мы не получим данные, поэтому было бы лучше использовать WeakReference в этих случаях, и это также поможет в управлении памятью, поскольку мы никогда не будем придерживаться сильной ссылки на наш Activity, тогда он будет иметь право на сбор мусора после его искажения.

Проверьте ниже фрагмент кода, чтобы узнать, как использовать awesome 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 реализации interface в этом классе и override этот обязательный метод.

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);
    }
}
3
ответ дан Rahul 27 August 2018 в 19:27
поделиться

Я работаю, используя потоки и обработчик / сообщение. Шаги, следующие: Объявите прогресс Диалог

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
ответ дан RAY 27 August 2018 в 19:27
поделиться

Вы можете сделать это в нескольких строках, просто переопределите onPostExecute при вызове AsyncTask. Вот вам пример:

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

Надеюсь, это помогло вам, счастливая трединга:)

6
ответ дан Sa Qada 27 August 2018 в 19:27
поделиться

Есть несколько вариантов:

  • Устанавливает класс 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
        ...
    }
    
22
ответ дан user113215 27 August 2018 в 19:27
поделиться

в вашем 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();

}`

4
ответ дан user3691697 27 August 2018 в 19:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: