我有一个方法调用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吗?
你永远不应该等待主线程,并在主线程上调用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
你必须附加到生命周期,不泄漏活动或片段。
尝试先调用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());
}
});
在异步类中进行网络调用,并使用下面提到的代码
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()
}
}
}
如果你在主线程上调用你的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();
}
}
}