继续整理一下做 Android 开发过程中遇到的一些问题和技巧。
1. 4.0 或以上版本的 Android 不能在主线程中联网
Android 应用程序运行在一个 dalvik 虚拟机进程中,当这个进程开始的时候会启动一个主线程( MainThread ),在 Android 4.0 或以上的版本中,强制禁止在主线程执行耗时的网络操作,若需要进行网络操作,则需要另外开辟线程或使用 AsyncTask ,下面介绍的是另外开辟线程的方法。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.single); new Thread(postLoad).start(); } Runnable postLoad = new Runnable(){ @Override public void run() { // TODO Auto-generated method stub // 在这里执行联网操作 } };
但是,联网操作后一般都需要根据联网所得数据更新 UI ,这时又会产生一个新问题,主线程负责处理和 UI 相关的操作,因此主线程又被称为 UI 线程。而 Android 采用 UI 单线程模型,只能在主线程中对 UI 元素进行操作,在非 UI 线程直接对 UI 进行了操作,则会报错。
为了解决这个问题,则需要利用 Android 的消息循环的机制实现线程间的通信。即在非 UI 线程发送消息到 UI 线程,让 UI 线程来进行 UI 的操作。例如,可以利用 View 的 post 方法告知 UI 线程执行操作更新 UI 。
Runnable postLoad = new Runnable(){ @Override public void run() { // TODO Auto-generated method stub // 联网获取数据 data TextView textShow = (TextView) findViewById(R.id.show); textShow.post(new Runnable() { @Override public void run() { // 该方法会在 ui 线程执行 textShow.setText(data); } }); } };
2. 检测是否有网络
final ConnectivityManager mConnectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); // 检查网络连接,如果无网络可用,就不需要进行连网操作等 NetworkInfo info = mConnectivity.getActiveNetworkInfo(); if (info != null ) { // 若有网络 // 判断网络连接类型 int netType = info.getType(); int netSubtype = info.getSubtype(); if (netType == ConnectivityManager.TYPE_WIFI) { // 若为 WIFI } else if (netType == ConnectivityManager.TYPE_MOBILE && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS ) { // 若为 3G } else { // 其他网络 } } else { // 若无网络 }
3. 自定义 touch 创建左右划动检测
// 定义手势速度记录器 private VelocityTracker velocityTracker; // 定义手势动作两点之间的距离要求 private static final int VELOCITYX = 900; private static final int VELOCITYY = 800; WebView postContent = (WebView) findViewById(R.id.postContent); postContent.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { // TODO Auto-generated method stub switch(arg1.getAction()){ case MotionEvent.ACTION_DOWN: if(velocityTracker == null){ // 取得手势在屏幕上的滑动速度 velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(arg1); } break; case MotionEvent.ACTION_MOVE: if(velocityTracker != null){ velocityTracker.addMovement(arg1); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_OUTSIDE: break; case MotionEvent.ACTION_UP: int velocityX = 0, velocityY = 0; if(velocityTracker != null){ velocityTracker.addMovement(arg1); velocityTracker.computeCurrentVelocity(1000); // 计算每秒滑动多少个像素 velocityX = (int) velocityTracker.getXVelocity(); // 最后计算检索 X 速度 velocityY = (int) velocityTracker.getYVelocity(); // 最后计算检索 Y 速度 } // 从右向左划 if( velocityX < -VELOCITYX && velocityY < VELOCITYY && velocityY > -VELOCITYY ){ // 执行相应操作 return true; } else if( velocityX > VELOCITYX && velocityY < VELOCITYY && velocityY > -VELOCITYY ) { // 从左向右划 // 执行相应操作 return true; } else { // 判断若不是划动操作,则返回 false 使用 WebView 自身的 touch 处理 return false; } } return false; } });
在检测过程中发现触摸操作不完整(例如划动距离太少,或者误触屏幕),或是直接判断出不是划动操作,必须返回 false ,使到组件自身的 touch 处理得以保留。
本文由 Kayo Lee 发表,本文链接:https://kayosite.com/some-problems-of-android-development-part-two.html
评论列表
技术文章啊~看不懂~有前途~
搞安卓开发的现在工资很高!
我同学做安卓测试的,我程序菜鸟