新人培训 – 线程&Handler

多线程


本次培训要搞清的几个问题
1.什么是线程
2.为什么Android只允许在主线程更新UI
3.如何异步进行耗时操作后在主线程执行回调更新UI
4.Handler的基本原理


线程的五个状态新建就绪执行等待销毁

  • 新建线程需要调用start()方法才会进入就绪状态
  • 处于就绪状态的线程并不一定立即被执行,而是听从CPU调度,即将被执行,所以被称为就绪
  • 处于等待状态的线程不会被CPU调度

如何创建新的线程


方法一

public class TestThread extends Thread {
    //默认构造方法
    public TestThread(){}

    //传入的String参数为线程名称
    public TestThread(String name) {
        super(name);
    }
    //该方法在线程由就绪转为执行时被调用
    @Override
    public void run() {
        super.run();
        System.out.println(this.getName());
    }
}

这样我们已经声明了自己的线程类,对于不同的线程,他们的区别主要在于他们的run()方法内的业务逻辑不同,同时我们需要注意的是,我们还没有实例化对象,也就是说现在新的线程还没有被创建.

继续阅读

Android 事件分发机制

前言

我们都知道给一个控件注册点击事件是只需要setOnClickListener,传入一个实现了onClick方法的匿名内部类,注册触摸事件只需要setOnTouchListener,传入一个实现了onTouch方法的匿名内部类,但是你会发现onTouch不同于onClick的一点是它是具有返回值的,这个返回值有什么用呢,onTouch和onClick方法谁先被调用呢?他们都是在那个函数中被调用的呢?下面我们就来看一看!

基础

//
button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                System.out.println("onTouch");
                return false;
            }
        });
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("onClick");
            }
        });
//
 09:37:30.432 6758-6758/com.example.administrator.mydemo I/System.out: onTouch
 09:37:30.538 6758-6758/com.example.administrator.mydemo I/System.out: onTouch
 09:37:30.541 6758-6758/com.example.administrator.mydemo I/System.out: onTouch
 09:37:30.548 6758-6758/com.example.administrator.mydemo I/System.out: onClick

 

我们可以看到onTouch是先于onClick被调

用的,那么我们在手都抛一个异常来看一下他的函数调用栈

//
at com.example.administrator.mydemo.MainActivity$1.onTouch(MainActivity.java:29)
at android.view.View.dispatchTouchEvent(View.java:11730)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1828)
at android.app.Activity.dispatchTouchEvent(Activity.java:3360)
//

这个只是截取了一部分,我们只看到追溯到Activity即可,所以对于onTouch方法,它是这样被调用的 … … -> Activity.dispatchTouchEvent -> PhoneWindow.superDispatchTouchEvent -> DecorView.superDisparchTouchEvent -> ViewGroup.dispatchTouchEvent – > ViewGroup.dispatchTransformedTouchEvent -> View.dispatchTouchEvent 那我们就可以按照这个顺序来看一看正常情况下的事件流的流向和相关函数代码

同时我们也可以看出对Touch事件它是由Activty->ViewGroup->View三层结构由外到内,Android5.0后代码变得更复杂了,但是原理没有变,我们就看一看便于理解的老代码

在开始之前为了第一次接触的人便于理解,我就简单的把情况设置为这个Activity中只有一个Layout,Layout中只有一个Button,所以只有一个Activty,一个ViewGroup,一个View,但是你要明白的是在安卓里ViewGroup也是一个View,View拥有dispatch方法,而ViewGroup作为它的子类重写了该方法,在后面提到时你要区分它调用的是作为Layout(ViewGroup)的dispatch方法,还是Layout作为一个View的dispatch方法!!!另外你还要区分ViewGroup是View的子类,Button是ViewGroup的子view

继续阅读

微北洋-代码读后感(1)

如何绘制一条优秀的GPA曲线

(1)准备工作

在布局文件中我们发现了很多自定义View,找到GPA曲线的自定义GpaLineChartView

//
<xyz.rickygao.gpa2.view.GpaLineChartView
    android:id="@+id/cv_gpa_line"
    android:layout_width="match_parent"
    android:layout_height="320dp"
    android:background="@color/gpa2_color_secondary"
    android:paddingBottom="160dp"
    android:paddingTop="40dp"
    app:fillColor="@color/gpa2_color_primary"
    app:lineColor="@color/gpa2_color_primary_dark"
    app:pointColor="@color/gpa2_color_primary_dark" />

//

 

在APP中对应红线部分

 

下面是该View的布局说明,除去四周的padding,实际的画布大小为图中红线部分

对应APP中位置,实际设置中Left和Right padding均为0dp 继续阅读