Как вызвать onPostExecute только после завершения метода в doinbackground? - PullRequest
1 голос
/ 06 июля 2019

Я вызываю это в onClickListener

AsyncTaskBindService asyncTaskBindService = new AsyncTaskBindService(position, songList);

asyncTaskBindService.execute();

Класс Asynctask

public class AsyncTaskBindService extends AsyncTask<Void, Void, Void>{

    private int songIndex;
    private ArrayList<Song> songList;

    public AsyncTaskBindService(int songIndex, ArrayList<Song> songList){
        this.songIndex = songIndex;
        this.songList = songList;
    }

    @Override
    protected Void doInBackground(Void... voids) {
        try {
            if (getActivity() != null && !Main.mServiceIsBound) {
                Main.bindMusicService(getActivity().getApplicationContext());
                Log.i(TAG,"binding service!");
            }
        }catch (Exception e){
            Log.e(TAG,"error binding Service!");
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        if (getActivity() != null && Main.mServiceIsBound) {
            Main.mediaPlayerService.startActionPlay(getActivity().getApplicationContext(), songList, songIndex);
            Log.i(TAG,"start song!");
        }
    }

Проблема в моем doInBackground:

Эта строка:

Main.bindMusicService(getActivity().getApplicationContext());

Этот метод вызывает bindService в другом классе, который затем возвращает экземпляр моей службе.

Но проблема в том, что Asynctask закончил путь к быстрому, и когда вызывается onPostExecute, он возвращает NPE, потому что mediaPlayerService по-прежнему равен нулю, поскольку onServiceConnected медленнее, чем моя Asynctask.

Как это решить?

Теперь мне нужно нажать на песню 2 раза, прежде чем она начнет играть.

EDIT

Сначала я попробовал это, но мой второй, если никогда не вызывается, потому что требуется некоторое время, прежде чем onServiceConnected () закончится.

Как я могу немедленно выполнить свой второй метод, если bindService завершен и моя служба привязана?

onClick Song

if (!Main.mServiceIsBound && getActivity() != null) {
        Main.bindMusicService(getActivity().getApplicationContext());
        Log.i(TAG,"Service is not bound yet!, binding Service...");
    }
    if (getActivity()!= null && Main.mServiceIsBound) {
        Main.mediaPlayerService.startActionPlay(getActivity().getApplicationContext(), songList, position);
    }

Основной класс

/**This establishes the connection to the MediaPlayerService. */
public static ServiceConnection serviceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MediaPlayerService.MusicBinder binder = (MediaPlayerService.MusicBinder)service;
        mediaPlayerService = binder.getService();
        mServiceIsBound = true;
        Log.i("Main","MediaPlayerService Connected!");
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mServiceIsBound = false;
        Log.i("Main","MediaPlayerService Disconnected!");
    }
};

public static void bindMusicService(Context c){
    /*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
    try{
    mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
    c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }catch (Exception e){
        Log.e("Main", "Service is not bound!");
    }
    Log.i("Main","Service is bound!");
}

1 Ответ

0 голосов
/ 06 июля 2019

Это потому, что AsyncTask s doInBackGround работают асинхронно, но когда вы связываете компонент с Service с помощью bindService, который также запускается асинхронно, вызывая немедленный возврат Main.bindMusicService.

AnAsyncTask не является хорошим кандидатом для такой работы.Вы должны связываться со службой в основном потоке (поток пользовательского интерфейса) и прослушивать обратный вызов onServiceConnected объекта ServiceConnection.

...