美文网首页
常见问题总结

常见问题总结

作者: ccccccal | 来源:发表于2018-03-05 00:32 被阅读7次

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

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

    • 通过Looper的prepare方法创建MessageQueue
    • 通过loop方法找到和当前线程匹配的Looper对象me
    • 从me中取出消息队列对象mQueue
    • 在一个死循环中,从mQueue中取出Message对象
    • 调用每个Message对象的msg.target.dispatchMesssge方法
    • 也就是Handler的dispatchMessage 方法
    • 在dispatchMessage 根据Message对象的特点执行特定的方法

    注意问题:
    子线程创建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");  
        }  
    }  
    

    相关文章

      网友评论

          本文标题:常见问题总结

          本文链接:https://www.haomeiwen.com/subject/hjlcfftx.html