赞
踩
简单来说,业务当时的界面是有两种输入登录模式,其中密码登录模式有三个EditText还有一个显示验证码的ImageView(用Bitmap动态加载图片),然后手机号登录模式中只有两个EditText。
我在代码中通过传入的值来切换模式的切换,具体类似下面的代码。
private void initMode() { clearAnimation(); switch (mode){ case Login.LOGIN_PASSWORD: etLoginArea.setVisibility(View.GONE); etLoginPhone.setVisibility(View.GONE); etLoginAccount.setVisibility(View.VISIBLE); llLoginPassword.setVisibility(View.VISIBLE); llLoginValidCode.setVisibility(View.VISIBLE); getValidCode(); //通过网络获取验证码 btnLogin.setEnabled(false); break; case Login.LOGIN_PHONE: etLoginAccount.setVisibility(View.GONE); llLoginPassword.setVisibility(View.GONE); llLoginValidCode.setVisibility(View.GONE); etLoginArea.setVisibility(View.VISIBLE); etLoginPhone.setVisibility(View.VISIBLE); btnLogin.setEnabled(false); break; } } private void clearAnimation() { etLoginAccount.clearAnimation(); llLoginPassword.clearAnimation(); llLoginValidCode.clearAnimation(); etLoginArea.clearAnimation(); etLoginPhone.clearAnimation(); btnLogin.clearAnimation(); }
然后在界面中出现了错误。
具体错误表现为:
我的解决措施:
在三个方法都没有显著效果之后,我开始精准调参数,来定位到底是哪个控件出现问题,最后定位到时ImageView中加载bitmap时,才会出现之前的错误。
public void showValidCode(Bitmap bitmap) {
try {
//获取网络图片成功后调用这一行,其中ivLoginValidCode是llLoginValidCode内部的一个ImageView
ivLoginValidCode.setImageBitmap(bitmap);
}catch (Exception e){
e.printStackTrace();
}
}
在第一次加载bitmap时会出现错误日志:
2019-12-13 11:50:12.071 10658-10818/com.sys.washmashine W/System.err: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
2019-12-13 11:50:12.071 10658-10818/com.sys.washmashine W/System.err: at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7753)
2019-12-13 11:50:12.071 10658-10818/com.sys.washmashine W/System.err: at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1225)
2019-12-13 11:50:12.071 10658-10818/com.sys.washmashine W/System.err: at android.view.View.requestLayout(View.java:23093)
2019-12-13 11:50:12.072 10658-10818/com.sys.washmashine I/chatty: uid=10254(com.sys.washmashine) identical 8 lines
2019-12-13 11:50:12.072 10658-10818/com.sys.washmashine W/System.err: at android.view.View.requestLayout(View.java:23093)
2019-12-13 11:50:12.072 10658-10818/com.sys.washmashine W/System.err: at android.widget.ImageView.setImageDrawable(ImageView.java:571)
2019-12-13 11:50:12.072 10658-10818/com.sys.washmashine W/System.err: at android.support.v7.widget.AppCompatImageView.setImageDrawable(AppCompatImageView.java:100)
2019-12-13 11:50:12.072 10658-10818/com.sys.washmashine W/System.err: at android.widget.ImageView.setImageBitmap(ImageView.java:705)
2019-12-13 11:50:12.072 10658-10818/com.sys.washmashine W/System.err: at android.support.v7.widget.AppCompatImageView.setImageBitmap(AppCompatImageView.java:108)
结果发现是传统的非主线程不能修改ui的错误。
然后才发现当时在申请图片的post接口中是new Thread().run()执行的。结果申请之后并没有通过handler到主线程再加载。最终就出了这个错误。
public void getValidCodeCode(String uuid) { final String path = ("xxx" + uuid); //地址不是原先的地址 new Thread() { public void run() { try { HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection(); conn.setConnectTimeout(30 * 1000); conn.setRequestMethod("POST"); InputStream inputStream = conn.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); inputStream.close(); showValidCode(bitmap); } catch (Exception e) { e.printStackTrace(); } } }.start(); }
但是实际上只有在第一次执行setImageView的时候,才会报错,后面执行的时候是不会报错的。也就是说其实子线程是可以执行Imageview.setImageBitmap这行代码。
所以我猜测出错的原因是在一部分手机上出现了线程不同步的错误,才导致了这个问题。
最后为了解决这个问题,用上了只有一个线程的线程池来节约反复打开线程的消耗问题。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。