是否有可能使setOnClickListener块等待它内部的方法调用?

问题描述 投票:1回答:4

我有一个方法调用setOnClickListener块中的第一个东西,它从我用来启动实时流的API获取一些值,这对于该方法调用至关重要,在块内部完成任何其他操作之前完成以获得正确的结果是因为第一行方法调用之后的所有其他内容都依赖于此。

代码段:

myButton.setOnClickListener {

            // Everything depends on check stream call
            currentViewModel.checkStream()

            if (!PlaybackService.isServiceStarted) {
                if (isStreaming!!) {
                    onPlayerStart()
                    sliding_player.panelState = SlidingUpPanelLayout.PanelState.COLLAPSED
                } else
                    Snackbar.make(appbar, R.string.stream_fail, Snackbar.LENGTH_LONG).show()
            }
        }

我需要myButton.setOnClickListener块等待 currentViewModel.checkStream()以便以下行正常工作(给出正确的结果)。

有可能吗?使用某种回调方法?我应该考虑使用Retrofit2吗?

android kotlin retrofit2
4个回答
1
投票

你永远不应该等待主线程,并在主线程上调用onClick()

您可以考虑使用异步框架来处理您的用例。这些框架将包括RxJava,AsyncTask甚至简单的Handler实现。为了更接近您的实际实现,Kotlin Coroutines可能是最合适的,因为切换回主线程非常清楚。它还与Retrofit很好地集成。

myButton.setOnClickListener {
    coroutineScope.launch(Dispatchers.IO) {
        // make sure checkStream() is a suspending function
        // to wait for it execution to finish
        currentViewModel.checkStream()

        if (!PlaybackService.isServiceStarted) {
            launch(Dispatchers.Main) {
                if (isStreaming!!) {
                    onPlayerStart()
                    sliding_player.panelState = COLLAPSED
                } else {
                    Snackbar.make(appbar, R.string.stream_fail, LENGTH_LONG).show()
                }
            }
        }
    }
}

coroutineScope你必须附加到生命周期,不泄漏活动或片段。


0
投票

尝试先调用api然后得到响应,就像这样调用你的方法..

Call<UploadObject> fileUpload = uploadImage.uploadFile(fileToUpload, filename);
        fileUpload.enqueue(new Callback<UploadObject>() {
            @Override
            public void onResponse(Call<UploadObject> call, Response<UploadObject> response) {
                Toast.makeText(MainActivity1.this, "Success " + response.message(), Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity1.this, "Success " + response.body().toString(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<UploadObject> call, Throwable t) {
                Log.d(TAG, "Error " + t.getMessage());
            }
        });

0
投票

在异步类中进行网络调用,并使用下面提到的代码

myButton.setOnClickListener {
    //start asycn call from here
    // new Async().execute();
        }

class Async extends Async{
    onPreExecute(){}

    doInBackground(){
        // below method call should be synchronised
        currentViewModel.checkStream()
    }

    onPostExecute(){
        if (!PlaybackService.isServiceStarted) {
                if (isStreaming!!) {
                    onPlayerStart()
                    sliding_player.panelState = SlidingUpPanelLayout.PanelState.COLLAPSED
                } else
                    Snackbar.make(appbar, R.string.stream_fail, Snackbar.LENGTH_LONG).show()
            }
    }

}

0
投票

如果你在主线程上调用你的API,它可能会卡住你的UI。因此,最好的方法是以异步方式调用API,并在API返回成功后执行更多代码。

检查下面的AsyncTask调用。

public class AsyncUploadStream extends AsyncTask<String, Integer, Object> {

    private ProgressDialog dialog;

    public AsyncUploadStream() {   
        dialog = new ProgressDialog(context);
        dialog.setMessage("Please Wait...");
    }

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

    @Override
    public Object doInBackground(String... params) {
        return currentViewModel.checkStream();
    }

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

        if (dialog != null && dialog.isShowing())
            dialog.dismiss();

        try {

            if (!PlaybackService.isServiceStarted) {
                if (isStreaming !!){
                    onPlayerStart()
                    sliding_player.panelState = SlidingUpPanelLayout.PanelState.COLLAPSED
                } else{
                    Snackbar.make(appbar, R.string.stream_fail, Snackbar.LENGTH_LONG).show()
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.