Android开发中Can't toast on a thread that has not called Looper.prepare()问题

说一下问题出现场景:

  在一个Android项目中,利用okhttp进行网络访问判断用户输入的账号密码,当用户密码输错时弹出 Toast 进行提示。

截取部分代码如下:

  利用okhttp进行网络访问代码(其中User类是用来包装用户名和密码):

import com.hzau.xiaonongfu.Entity.User;
import okhttp3.*;


public class HttpUtil {
    private static final String TAG="HttpUtil";

    private static final OkHttpClient client=new OkHttpClient().newBuilder().build();



    //用户登录验证
    public static void login(User user,okhttp3.Callback callback){
        //建立表单,添加需要上传到服务器的参数
        RequestBody body=new FormBody.Builder()
                .add("username",user.getUser_name())
                .add("password",user.getPassword())
                .build();


        //发起请求
        Request request=new Request.Builder()
                .url(Address.LOGIN_ADDRESS)
                .post(body)
                .build();

        //启动连接,enqueue()会自动开启子线程
        client.newCall(request).enqueue(callback);
    }
}

在Activity中获取返回数据:

HttpUtil.login(user,new okhttp3.Callback(){
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String s= Objects.requireNonNull(response.body()).string();
//判断是否登录成功
if(s.equals("0")){
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}else if(s.equals("1")){
Toast.makeText(LoginActivity.this,"密码错误,请检查您的密码!",Toast.LENGTH_SHORT).show();
}
}

@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {

}
});

这里服务器端采用php脚本的方式,账号密码正确就返回 0 ,错误就返回 1 。

 

百度了一下,说一下错误的原因吧:

  okhttp中 Callback 是封装好的在子线程运行,Android是不允许在子线程中弹出 Toast 提示的,和不允许在子线程中进行 UI 操作一样。

 

 

解决办法:

在 Toast 前后加上一些代码,如下:

Looper.prepare();
Toast.makeText(LoginActivity.this,"密码错误,请检查您的密码!",Toast.LENGTH_SHORT).show();
Looper.loop();

以后有空回来补充其中原理。

吾生也有涯,而知也无涯。

 

  

12-30 14:57