常见问题总结

2018-03-05  本文已影响7人  ccccccal

handler机制,使用时一般会遇到的问题有

在子线程中handler使用handler.senMessage等方法发送消息到消息队列messagequeue,一个handler会对应产生一个looper,一个looper会对应一个消息队列,looper会反复对消息队列的轮询,如果查到消息,就把消息指定给对应创建消息的hander去处理。

注意问题:
子线程创建handler必须指定looper

1、创建一个HandlerThread,即创建了一个包含Looper的线程。
HandlerThread handlerThread = new HandlerThread(“HandlerThread”);
handlerThread.start(); //创建HandlerThread后一定要记得start()

2、获取HandlerThread的Looper
Looper looper = handlerThread.getLooper();

3、创建Handler,通过Looper初始化
Handler handler = new Handler(looper);

4.想让HandlerThread退出,则需要调用handlerThread.quit()

private HandlerThread  handlerThread = new HandlerThread("handler thread");
    handlerThread.start();

    handler = new Handler(handlerThread.getLooper()){//现成的Looper
        @Override
        public void handleMessage(Message msg) {
            System.out.println("currentThread->"+Thread.currentThread());
        }
    };

只能在UI线程更新界面吗

1、使用Handler
2、用Activity对象的runOnUiThread方法
3、View.post(Runnable r)
4、Broadcast子线程中发送广播,主线程中接收广播并更新UI
5、AsyncTask

class TestThread extends Thread{
        @Override
        public void run() {
            Looper.prepare();
            TextView tx = new TextView(MainActivity.this);
            tx.setText("时间煮雨");
            tx.setTextColor(getResources().getColor(R.color.white));
            tx.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
            tx.setGravity(Gravity.CENTER);
            WindowManager wm = MainActivity.this.getWindowManager();
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    250, 150, 200, 200, WindowManager.LayoutParams.FIRST_SUB_WINDOW,
                    WindowManager.LayoutParams.TYPE_TOAST, PixelFormat.OPAQUE);
            wm.addView(tx, params);
            Looper.loop();
        }
    }

android内存溢出OOM

  1. 图片过大
    • 等比缩放
    • 采用软应用
    • 使用第三方框架
      2.多次横竖屏切换
    • 清单文件配置,保持activity的生命周期
      3.数据库没有关闭游标
      4.Bitmap对象不再使用时调用recycle()来释放对象。

android造成内存泄漏的常见原因以及会产生什么问题,以及处理方式有(android Profiler以及leakcanary进行检查)

  1. context
    工具类持有activity对象,大部分都是static

2.内部类的种种问题
handler,thread以及dialog等

public class LeakActivity extends Activity {

  /**
   * 声明静态内部类不会持有外部类的隐式引用
   */
  private static class MyHandler extends Handler {
    private final WeakReference<SampleActivity> mActivity;

    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference<SampleActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
        // ...
      }
    }
  }

  private final MyHandler mHandler = new MyHandler(this);

  /**
   * 这里的Runnable也是 
   * 声明静态内部类不会持有外部类的隐式引用
   */
  private static final Runnable sRunnable = new Runnable() {
      @Override
      public void run() { /* ... */ }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //10分钟之后发送消息 
    mHandler.postDelayed(sRunnable, 1000 * 60 * 10);

    // 退回到上一个Activity
    finish();
  }
}


@Override
public void onDestroy() {
   //简单粗暴
    mHandler.removeMessages(message);
    mHandler.removeCallbacks(Runnable);
    mHandler.removeCallbacksAndMessages(null);
}
  1. 广播记得取消注册

  2. 数据库游标

  3. Bitmap对象不再使用时调用recycle()来释放对象。

6.未关闭InputStream/OutputStream

activity的缓存

public void onSaveInstanceState(Bundle savedInstanceState){  
    savedInstanceState.putBoolean("MyBoolean",true);  
    saveInstanceState.putDouble("MyDouble",1.9);  
    savedInstanceState.putInt("MyInt",1);  
    savedInstanceState.putString("MyString","Android");  
    super.onSaveInstanceState(savedInstanceState);  
}  
public void onRestoreInstanceState(Bundle savedInstanceState){  
    super.onRestoreInstanceState(savedRestoreInstanceState);  
    boolean myBoolean = saveInstanceState.getBoolean("MyBoolean");  
    double myDouble = saveInstanceState.getDouble("MyDouble");  
    int myInt = saveInstanceState.getInt("MyInt");  
}  
    protected void onCreate(Bundle savedInstanceState){  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
    //      当activity第一次被创建的时候为空  
    //      所以我们来判断一下  
    if(savedInstanceState != null){  
        savedInstanceState.getString("anAnt");  
    }  
}  
上一篇下一篇

猜你喜欢

热点阅读