Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用UI线程改进2个回调问题_Android_Retrofit2_Android Handler_Ui Thread - Fatal编程技术网

Android 使用UI线程改进2个回调问题

Android 使用UI线程改进2个回调问题,android,retrofit2,android-handler,ui-thread,Android,Retrofit2,Android Handler,Ui Thread,我正在制作一个简单的材料设计登录屏幕,在改造获取数据时显示一个进度对话框 我最近升级到了翻新2,所以我对这一点很陌生 我的LoginActivity代码: private void login(){ Log.d(TAG, "Attempting login"); if(!validate()){ onLoginFailure(); return; } login_button.se

我正在制作一个简单的材料设计登录屏幕,在改造获取数据时显示一个进度对话框

我最近升级到了翻新2,所以我对这一点很陌生

我的LoginActivity代码:

private void login(){
        Log.d(TAG, "Attempting login");

        if(!validate()){
            onLoginFailure();
            return;
        }

        login_button.setEnabled(false);

        progressDialog = new ProgressDialog(LoginActivity.this, R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Authenticating...");
        progressDialog.show();

        String username = _usernameText.getText().toString().toLowerCase(); //all usernames are lowercase only
        String password = _passwordText.getText().toString();

        //here we handle the NWL section.

        startTime = System.currentTimeMillis();
        NWL.login(username, password, this); //This runs async to UI anyway.
    }
@BindView(R.id.login_button)
Button login_button;

 public void loginOK() {
        progressDialog.dismiss();
        login_button.setEnabled(true);
        toastCreator.showToastLong("Login OK");
        Log.d(TAG, "Total time: " + (System.currentTimeMillis()-startTime));
 }
以及LoginActivity中的其他功能:

private void login(){
        Log.d(TAG, "Attempting login");

        if(!validate()){
            onLoginFailure();
            return;
        }

        login_button.setEnabled(false);

        progressDialog = new ProgressDialog(LoginActivity.this, R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Authenticating...");
        progressDialog.show();

        String username = _usernameText.getText().toString().toLowerCase(); //all usernames are lowercase only
        String password = _passwordText.getText().toString();

        //here we handle the NWL section.

        startTime = System.currentTimeMillis();
        NWL.login(username, password, this); //This runs async to UI anyway.
    }
@BindView(R.id.login_button)
Button login_button;

 public void loginOK() {
        progressDialog.dismiss();
        login_button.setEnabled(true);
        toastCreator.showToastLong("Login OK");
        Log.d(TAG, "Total time: " + (System.currentTimeMillis()-startTime));
 }
我的NetworkLogic(NWL)类中的代码:

public void登录(字符串用户名、字符串密码、最终登录活动LoginActivity){
LoginUser LoginUser=新登录用户(用户名、密码);
Call Call=apiService.login(loginUser);
Log.d(TAG,call.toString());
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
Log.d(标记“Responsecode:+response.code());
试一试{
Thread.sleep(2000);//测试progressdialog是否实际显示
}捕捉(中断异常e){
e、 printStackTrace();
}
if(response.code()==200){
loginActivity.loginOK();
}否则{
loginActivity.loginFail();
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.d(标记“Failed:+t.getMessage());
loginActivity.loginFail();
}
});
}
现在,我不断收到错误,例如: -android.util.AndroidRuntimeException:动画师只能在活套线程上运行(关于登录按钮) -java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序(关于toastCreator)

我理解问题的原因(来自改型2的异步线程正在进行调用),它应该将调用传递给ui线程。 我的问题是,处理这个问题的最佳解决方案是什么?当然,我可以用CountdownLatch一起破解一些代码,并以强制同步的方式运行整个异步调用,但这并不是我真正想要的。 我应该使用处理程序吗?如果是的话,实施这一点的最佳方式是什么

所有代码均可用:


期待答案

改型onResponse在UI线程上工作,所以您的thread.sleep()会给您带来问题

 Thread.sleep(2000); //This line must not be on UI thread.

如果您需要一些延迟,您可以轻松地使用handler。

好的,因为没有人正确地回答了这个问题,现在开始

使用处理程序并向其发送消息似乎可以达到目的

在onCreate方法中:

handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg){
            switch (msg.what){
                case 200:
                    //Got the good response
                    loginOK();
                    break;
                case 401:
                    loginFail();
                    break;
                default:
                    loginFail();
            }
        }
    };
在我的networklogic课程中:

Call<Username> call = apiService.login(userObject);
    call.enqueue(new Callback<Username>() {
       @Override
       public void onResponse(Call<Username> call, Response<Username> response) {
           Log.d(TAG, "Responsecode: " + response.code());
           Message msg = handler.obtainMessage(response.code());
           msg.sendToTarget();

       }

       @Override
       public void onFailure(Call<Username> call, Throwable t) {
           Log.d(TAG, "Failed: " + t.getMessage());
           Message msg = handler.obtainMessage(0); //0 for errors
           msg.sendToTarget();
       }
}
Call Call=apiService.login(userObject);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
Log.d(标记“Responsecode:+response.code());
Message msg=handler.obtainMessage(response.code());
msg.sendToTarget();
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.d(标记“Failed:+t.getMessage());
Message msg=handler.obtainMessage(0);//错误为0
msg.sendToTarget();
}
}
因为这是在mainLooper上运行的,所以我可以在这些函数中任意使用我的UI。
这应该是正确答案。

删除thread.sleep仍然会导致我的登录按钮出现问题。setEnabled(true)。错误:android.util.AndroidRuntimeException:动画师只能在活套线程上运行请发送完整的堆栈跟踪。错误代码(故意提供错误密码):