Android 多线程

01.Android中的线程

  • 主线程(有的也成UI线程)
    • 在Android当中, 当应用启动的时候,系统会给应用分配一个进程,顺便一提,大部分应用都是单进程的,不过也可以通过设置来使不同组件运行在不同的进程中,在创建进程的同时会创建一个线程,应用的大部分操作都会在这个线程中运行。所以称为主线程,同时所有的UI控件相关的操作也要求在这个线程中操作,所以也称为UI线程。
  • 为何会有子线程
    • 因为所有的UI控件的操作都在UI线程中执行,如果在UI线程中执行耗时操作,例如网络请求等,就会阻塞UI线程,导致系统报ANR(Application Not Response)错误。因此对于耗时操作需要创建工作线程来执行而不能直接在UI线程中执行。这样就需要在应用中使用多线程,但是Android提供的UI工具包并不是线程安全的,也就是说不能直接在工作线程中访问UI控件,否则会导致不能预测的问题, 因此需要额外的机制来进行线程交互,主要是让其他线程可以访问UI线程。
阅读更多

Android View 事件总结2

01.View滑动有哪些方法

  • View滑动有哪些方法?

    • layout:对View进行重新布局定位。在onTouchEvent()方法中获得控件滑动前后的偏移。然后通过layout方法重新设置。
    • offsetLeftAndRight和offsetTopAndBottom:系统提供上下/左右同时偏移的API。onTouchEvent()中调用
    • LayoutParams: 更改自身布局参数
    • scrollTo/scrollBy: 本质是移动View的内容,需要通过父容器的该方法来滑动当前View
阅读更多

Android View 事件总结1

01.Android事件分发机制

  • 简述Android的事件分发机制?
    • 事件分发顺序:Activty->ViewGroup->View
    • 主要方法:dispatchTouchEvent-分发事件、onInterceptTouchEvent-当前View是否拦截该事件、onTouchEvent-处理事件
    • 1.父View调用dispatchTouchEvent开启事件分发。
    • 2.父View调用onInterceptTouchEvent判断是否拦截该事件,一旦拦截后该事件的后续事件(如DOWN之后的MOVE和UP)都直接拦截,不会再进行判断。
阅读更多

Android View事件机制

1.事件机制代码解释说明

1.1 触摸事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 触摸事件
* 如果返回结果为false表示不消费该事件,并且也不会截获接下来的事件序列,事件会继续传递
* 如果返回为true表示当前View消费该事件,阻止事件继续传递
*
* 在这里要强调View的OnTouchListener。如果View设置了该监听,那么OnTouch()将会回调。
* 如果返回为true那么该View的OnTouchEvent将不会在执行 这是因为设置的OnTouchListener执行时的优先级要比onTouchEvent高。
* 优先级:OnTouchListener > onTouchEvent > onClickListener
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("onEvent","MyLinearLayout onTouchEvent");
return super.onTouchEvent(event);
}
阅读更多

Android View 的滑动冲突

01.什么是滑动冲突

  • 当父容器与子 View 都可以滑动时,就会产生滑动冲突。
  • 解决 View 之间的滑动冲突的方法分为两种,分别是外部拦截法和内部拦截法

02.外部拦截法

  • 父容器根据需要在 onInterceptTouchEvent 方法中对触摸事件进行选择性拦截,思路可以看以下伪代码

阅读更多

Android View 事件分发场景

01.事件分发背景描述

  • 讨论的布局层次如下:
    • 最外层:Activiy A,包含两个子View:ViewGroup B、View C
    • 中间层:ViewGroup B,包含一个子View:View C
    • 最内层:View C
  • 触摸情况
    • 假设用户首先触摸到屏幕上View C上的某个点(如图中黄色区域),那么Action_DOWN事件就在该点产生,然后用户移动手指并最后离开屏幕。
阅读更多

Android View 事件机制源码分析

01.Android中事件分发顺序

  • Android中事件分发顺序:
    • Activity(Window) -> ViewGroup -> View
  • 其中:
    • super:调用父类方法
    • true:消费事件,即事件不继续往下传递
    • false:不消费事件,事件继续往下传递 / 交由给父控件onTouchEvent()处理
阅读更多

Android View 事件基础

01.事件分发概念

1.1 事件分发的对象是谁

  • 事件分发的对象是事件。注意,事件分发是向下传递的,也就是父到子的顺序。
  • 当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件)。
    • Touch事件相关细节(发生触摸的位置、时间、历史记录、手势动作等)被封装成MotionEvent对象
阅读更多

Android Android 保存多张图片到本地

01.实际开发保存图片遇到的问题

  • 业务需求

    • 在素材list页面的九宫格素材中,展示网络请求加载的图片。如果用户点击保存按钮,则保存若干张图片到本地。具体做法是,使用glide加载图片,然后设置listener监听,在图片请求成功onResourceReady后,将图片资源resource保存到集合中。这个时候,如果点击保存控件,则循环遍历图片资源集合保存到本地文件夹。
  • 具体做法代码展示

阅读更多

Android 加载大图流程

01.网络请求图片

  • 直接通过http请求网络图片通过流转化成Bitmap。实际开发中一般使用glide去请求加载图片资源。

  • 经过测试,请求8张图片,耗时毫秒值174。如果是服务器响应速度一般,耗时需要2秒【正式接口】。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    /**
    * 请求网络图片转化成bitmap
    * @param url url
    * @return 将url图片转化成bitmap对象
    */
    private static long time = 0;
    public static Bitmap returnBitMap(String url) {
    long l1 = System.currentTimeMillis();
    URL myFileUrl = null;
    Bitmap bitmap = null;
    HttpURLConnection conn = null;
    InputStream is = null;
    try {
    myFileUrl = new URL(url);
    } catch (MalformedURLException e) {
    e.printStackTrace();
    }
    try {
    conn = (HttpURLConnection) myFileUrl.openConnection();
    conn.setConnectTimeout(10000);
    conn.setReadTimeout(5000);
    conn.setDoInput(true);
    conn.connect();
    is = conn.getInputStream();
    bitmap = BitmapFactory.decodeStream(is);
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if (is != null) {
    is.close();
    conn.disconnect();
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    long l2 = System.currentTimeMillis();
    time = (l2-l1) + time;
    LogUtils.e("毫秒值"+time);
    //保存
    }
    return bitmap;
    }
阅读更多