Android 学习

Kotlin、Android、Jetpack、Java学习

  • Kotlin 篇
  • Android 篇
  • Jetpack 篇
  • Java 篇

Kotlin 篇

Kotlin 好多语法类似于 ES6 语法.
可以多看看ES6对前端或者其他开发语言都会有帮助.

  1. 断言 !! 不管是不是空值都执行后面的代码
fun main() {
    var name: String ?= null
    var aa = name !!.capitalize()
    println(aa) // Exception in thread "main" java.lang.NullPointerException
}
  1. 安全调用可控操作符, 用 ? 操作符避免出现空指针异常
var name: String ? = "james"
name = null
println(name?.capitalize())  // null

val num: Int? = "66.6".toIntOrNull()
println("num:$num") // null
  1. 匿名函数和具名函数
fun main() {
    // 匿名函数
    showPersonInfo("James", 20, "男", "学习kotlin") {
        println("1.显示个人信息: $it")
    }

    // 具名函数
    showPersonInfo("MeiMei", 22, "女", "学习C++", ::showResultImpl)
}

fun showResultImpl(result: String) {
    println("2.显示个人信息: $result")
}

inline fun showPersonInfo (name: String, age: Int, sex: String, study: String, showResult: (String) -> Unit) {
    val str = "name: $name, age: $age, sex: $sex, study: $study"
    showResult(str)
}
  1. lambda 函数
    匿名函数即 lambda 函数
    如果函数参数有 lambda, 尽量使用 inline 关键字, 这样内部会做优化,
    减少函数开辟,对象开辟的损耗.
    lambda属于函数类型的对象
// 模拟登录
fun main() {
    // lambda属于函数类型的对象,这里需要将responseResultFun普通函数改成函数类型的对象, 采用 ::
    login("hujian1", "123456", ::responseResultFun)
}

fun responseResultFun(msg: String, code: Int) {
    println("登录结果为,msg:${msg}, code:${code}")
}

const val USER_NAME_SAVE_DB = "hujian"
const val USER_PWD_SAVE_DB = "123456"

public inline fun login(name: String, pwd: String, responseResult: (String, Int) -> Unit) {
    if(USER_NAME_SAVE_DB == name && USER_PWD_SAVE_DB == pwd) {
        responseResult("登录成功!", 200) // 登录成功
    } else {
        responseResult("登录失败!", 500) // 登录失败
    }
}
  1. 匿名函数,返回值类型推断
fun main() {
    val anonymousFun = {
        num1: Int, dou2: Double, str3: String ->
        "参数1: ${num1}, 参数2: ${dou2}, 参数3: ${str3}"
    }
    println(anonymousFun(20, 11.22, "James"))

    val anonymousFun2 = {
        123.456
    }
    println(anonymousFun2())

    val anonymousFun3 = {
        num1: Int ->
        num1 + 1
    }
    println(anonymousFun3(999))
}
  1. 匿名函数,带参数
fun main() {
    val anonymousFun: (Int, Int, String) -> String = {
        num1, num2, str3 ->
        val inputValue = 123
        "$inputValue Let`s go, 参数1: ${num1}, 参数2: ${num2}, 参数3: ${str3}, "
    }
    println(anonymousFun(18, 20, "James"))
}
  1. 匿名函数不要写return, 最后一行就是返回值
fun main() {
    val anonymousFun: () -> String = {
        val inputValue = 123
        "$inputValue Let`s go"
    }
    println(anonymousFun())
}
  1. 反引号中的函数名
fun main() {
    // 第一种情况下使用
    `你好啊函数`("James", 18)

    // 第二种情况使用: in,is 在Java中可当字符串使用,但是在kotlin中是关键字
    TestClass.`is`()
    TestClass.`in`()
}
private fun `你好啊函数` (name: String, age: Int) {
    println("用户名:${name}, 年龄:${age}.")
}
  1. Nothing类型
fun main() {
    show(102)
}

private fun show(number:Int){
    when(number){
        in 0..59 -> println("不及格")
        in 60..100 -> println("及格")
        else -> TODO("没有这种分数") // TODO不是提示语句,而是抛出Nothing异常,终止程序的代码
    }
}
  1. Unit函数
    :Unit不写,默认也有. :Unit代表无参数返回. 类似Java里的void,区别是一个是关键字一个是Unit类型类.
fun main() {
    doWork()
}

private fun doWork() : Unit {
    println("开始编码")
}
  1. 函数头
    Android 学习_第1张图片

  2. String模板

val garden = "黄石公园"
var time = 4
println("今天去${garden}玩了${time + time}个小时")

var isLogin = true
println("登录状态: ${if(isLogin)"登录成功" else "登录失败"}")
  1. when表达式
val week = 8
val info = when (week) {
    1 -> "周一"
    2 -> "周二"
    3 -> "周三"
    4 -> "周四"
    5 -> "周五"
    6 -> "周六"
    7 -> "周日"
    else -> {
        println("其他")
    }
}
println(info)
  1. range表达式
val number = 101
if (number in 0 .. 59) {
    println("不及格")
} else if (number in 60 .. 100) {
    println("及格")
} else {
    println("分数不在0到100之间")
}
  1. 数据类型
    Java中有两种数据类型: (1)基本类型:int double等. (2)引用类型: String 等.
    Kotlin中只有一种数据类型,看起来都是引用类型,实际上编译器会在Java字节码中修改成"基本类型".

  2. 编译时常量
    const val PI = 3.14
    只能放在fun函数外

  3. val 不可修改的变量
    var name: String = “James”
    val name: String = “James” // 根据Kotlin语言类型推断,需要简写成 val name = “James”

  4. 内置数据类型
    String: 字符串
    Char: 单字符
    Boolean: true / false
    Int: 整型
    Double: 小数
    List: 集合
    Set: 无重复元素的集合
    Map: 键值对的集合

  5. kotlin介绍
    (1)集聚各个语言的精华
    (2)走向全栈语言

Android 篇

  1. gravity 和 layout_gravity
    android:gravity:是控件内部的对齐方式。可以理解为,本控件会影响到子控件的显示;
    android:layout_gravity:组件对于父容器的位置。它的参照物是“父控件”;

  2. 录制视频 MediaRecorder , 视频播放 MediaPlayer, 音效播放 SoundPool
    参考代码: C:\Users\HJ\Desktop\Android\Demo1\mediademo\src\main\java\com\example\mediademo

  3. bundle传递数据, 通过实现Parcelable 和 Serializable 接口来传递对象
    推荐方式: Android 中最好使用Parcelable,这个是安卓推荐,兼容安卓虚拟机,比Serializable性能高很多.

  4. Room三角色
    Student(Entity) StudentDao(DAO) StudentDatabase(DB)

  5. SQLite 介绍
    Android 学习_第2张图片

  6. 记录: 模拟器中 Toast.makeText().show(); 不展示的问题
    选择 AVD Manager, 执行一下 Wipe Data 操作,即可.

  7. 数据存储的选择
    主要有: SP SQLite Room
    (1) SP (sharedpreference 首选项)
    存储软件的配置信息: window是用的ini, android用的XML.
    应用场景:
    自动登录,记住密码,主题记录等等.
    首选项不能存储太多信息. 特点: 当程序运行首选项里面的数据会全部加载进内容.
    很小,很简单的数据可以考虑存到首选项里去. 采用键值对的形式存储.

  8. Java Object 、Array 、List 、Map 、Set 的序列化与反序列化
    参考视频
    List 、Map 、Set的反序列化需要获取下类型:
    Type type = new TypeToken() { }.getType();
    Type type = new TypeToken() { }.getType();
    Type type = new TypeToken() { }.getType();

  9. Retrofit 注解
    Android 学习_第3张图片

  10. Retrofit
    Android 学习_第4张图片Android 学习_第5张图片
    Android 学习_第6张图片

  11. OkHttp Cookie模拟代码

package com.example.hujian;

import androidx.annotation.NonNull;

import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class CookieUnitTest {
    Map<String, List<Cookie>> cookies = new HashMap<>();

    @Test
    public void cookieTest() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(@NonNull HttpUrl httpUrl, @NonNull List<Cookie> list) {
                        cookies.put(httpUrl.host(), list);
                    }

                    @NonNull
                    @Override
                    public List<Cookie> loadForRequest(@NonNull HttpUrl httpUrl) {
                        List<Cookie> cookies = CookieUnitTest.this.cookies.get(httpUrl.host());
                        return cookies == null ? new ArrayList<>() : cookies;
                    }
                })
                .build();

        FormBody formBody = new FormBody.Builder()
                .add("username", "18066117765")
                .add("password", "hujian761751953")
                .build();
        Request request = new Request.Builder().url("https://www.wanandroid.com/user/login")
                .post(formBody).build();
        //准备好请求的Call对象
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            System.out.println("登录: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }

        request = new Request.Builder().url("https://www.wanandroid.com/lg/collect/list/0/json")
                .build();
        //准备好请求的Call对象
        call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            System.out.println("获取收藏文章: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
  1. OkHttp POST请求
    Android 学习_第7张图片
// post 异步请求
public void postAsync(View view) {
    FormBody formBody = new FormBody.Builder().add("a", "1").add("b", "2").build();
    Request request = new Request.Builder().url("http://www.httpbin.org/post").post(formBody).build();
    //准备好请求的Call对象
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            Log.d("James", "异步post请求失败");
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if (response.isSuccessful()) {
                Log.d("James", "异步post请求: " + response.body().string());
            } else {
                Log.d("James", "异步post请求异常");
            }
        }
    });
}


@Test
public void uploadFileTest() throws IOException {
    OkHttpClient okHttpClient = new OkHttpClient();
    File file1 = new File("C:\\Users\\HJ\\Desktop\\test1.txt");
    File file2 = new File("C:\\Users\\HJ\\Desktop\\test2.txt");
    MultipartBody multipartBody = new MultipartBody.Builder()
            .addFormDataPart("file1", file1.getName(), RequestBody.create(file1, MediaType.parse("text/plain")))
            .addFormDataPart("file2", file2.getName(), RequestBody.create(file2, MediaType.parse("text/plain")))
            .build();
    Request request = new Request.Builder().url("http://www.httpbin.org/post").post(multipartBody).build();
    Call call = okHttpClient.newCall(request);
    Response response = call.execute();
    System.out.println(response.body().string());
}


@Test
public  void jsonTest() throws IOException {
    OkHttpClient okHttpClient = new OkHttpClient();
    RequestBody requestBody = RequestBody.create("{\"a\":\"1\", \"b\":\"2\"}", MediaType.parse("application/json"));
    Request request = new Request.Builder().url("http://www.httpbin.org/post").post(requestBody).build();
    Call call = okHttpClient.newCall(request);
    Response response = call.execute();
    System.out.println(response.body().string());
}
  1. OkHttp 的同步与异步请求
    参考视频

  2. Glide 变换

ImageView iv_test = findViewById(R.id.iv_test);
Glide.with(this).load(R.drawable.image)
        .transform(new RoundedCorners(50), new Rotate(90))
        .into(iv_test);

Android 学习_第8张图片

  1. 热修复
    在我们应用上线后出现bug需要及时修复时,不用再发新的安装包,只需要发布补丁包,在客户无感知下修复掉bug.
    使用 Bugly: https://bugly.qq.com/docs/
    Tinker是微信开源的一个热修复解决方案,支持dex、库和资源更新,无需重新安装apk.
    开源地址: https://github.com/Tencent/tinker

  2. @Nullable
    @Nullable可以用在方法、属性、参数上。对应的意思分别如下:
    方法:表示返回值可以是空
    属性:表示属性值可以是空
    参数:表示参数值可以是空

  3. Android的四大组件
    (1) Activity组件,它一个单独的窗口,程序流程都必须在【Activity】中运行,所有它是最基本的模块。
    (2) service组件,用于在后台完成用户指定的操作。
    (3) content provider组件,会为所有的应用准备一个内容窗口,并且保留数据库、文件。
    (4) broadcast receiver组件,是程序之间传递信息时的一种机制,作用就是接收或者发送通知。分为系统广播和用户自定义广播.

  4. 记录: xml中代码背景为黄色的

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/id_viewpager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">androidx.viewpager2.widget.ViewPager2>

将上面的代码改成单标签的形式

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/id_viewpager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />
  1. Fragment 生命周期
    Android 学习_第9张图片

  2. Activity 与 Fragment通信
    (1) 原生方案: Bundle
    (2) Java语言中类与类自己通信常用方案: 接口
    (3) 其他方案: eventBus、LiveData

  3. 记录: android studio avd 一直处于 Waiting for all target devices to come online
    试了各种方法都没用, 把这个AVD delete ,然后把 C:\Users\HJ.android\avd.android\avd 中相关文件删了,
    重新下载了一个AVD,一切都正常了,
    另外, Toast.makeText(FragmentManageActivity.this,“哈哈哈哈”,Toast.LENGTH_SHORT).show(); 不展示的问题也解决了.

  4. 动态添加Fragment
    Android 学习_第10张图片

  5. 记录: 新建一个module, xml文件中没有代码提示
    将此module下的build.gradle文件中的 compileSdk 33 改成 30 即可.

  6. Fragment 片段
    (1) 具备生命周期,可以看作是子activity
    (2) 必须委托在activity中才能运行.

  7. dp 和 sp
    (1) dip / dp : device independent pixels(设备独立像素),不同设备有不同的显示效果,这个和设备有关,一般我们为了支持WVGA、HVGA和QVGA推荐使用这个,不依赖像素px.
    (2) sp: scaled pixels(放大像素),主要用于字体显示.

  8. 补间动画
    Android 学习_第11张图片

  9. 动画启动和停止
    Android 学习_第12张图片

  10. 动画
    Android 学习_第13张图片

  11. ListView
    参考视频

  12. RelativeLayout, TableLayout, GridLayout
    参考视频

  13. LinearLayout
    Android 学习_第14张图片

  14. 分割线

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@color/purple_500"></View>
  1. PopupWindow
    Android 学习_第15张图片

  2. AlertDialog
    Android 学习_第16张图片

  3. 记录: Android Studio 中的AVD怎么都起不来,试了各种方法都没用.
    最后把那个版本的AVD删了,然后把 C:\Users\HJ.android\avd 里的两个对应AVD文件删了,
    重新下载了一个AVD就运行起来了.

  4. Notification
    参考视频

  5. ProgressBar
    Android 学习_第17张图片

  6. ImageView

当图片宽比较大,宽度到达300dp之后,图片就等比缩放到宽为300dp为止:
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:maxWidth="300dp"
    android:maxHeight="300dp"
    android:adjustViewBounds="true"
    android:background="@color/xingrenhuang"
    android:src="@drawable/background"></ImageView>

Android 学习_第18张图片
Android 学习_第19张图片

  1. EditText
    Android 学习_第20张图片

  2. 实现跑马灯效果
    需要添加焦点才能自动跑起来
    Android 学习_第21张图片

  3. TextView 带阴影
    Android 学习_第22张图片

  4. 记录: Android Studio xml 文件中没有代码提示
    在Gradle Scripts / build.gradle(Module:hujian.app)中,将compileSdk由33改为29
    都不用重启Android Studio,代码提示就都出来了.

  5. 向上一个Activity返回数据
    Android 学习_第23张图片

  6. Bundle
    Android 学习_第24张图片

  7. 向下一个Activity发送数据
    Android 学习_第25张图片

  8. 隐式Intent
    Android 学习_第26张图片

  9. Intent的组成部分
    Android 学习_第27张图片

  10. 各状态之间的切换过程
    Android 学习_第28张图片

  11. 生命周期
    参考视频
    在这里插入图片描述

  12. android 四大组件
    (1) Activity 组件,它一个单独的窗口,程序流程都必须在【Activity】中运行,所有它是最基本的模块。
    (2) service 组件,用于在后台完成用户指定的操作。
    (3) content provider 组件,会为所有的应用准备一个内容窗口,并且保留数据库、文件。
    (4) broadcast receiver 组件,是程序之间传递信息时的一种机制,作用就是接收或者发送通知。
    参考文章

  13. 图像视图的缩放类型
    (1) 代码中:
    ImageView iv_scale = findViewById(R.id.iv_scale);
    iv_scale.setImageResource(R.drawable.test);
    iv_scale.setScaleType(ImageView.ScaleType.FIT_XY);
    (2)XML文件中:
    android:src=“@drawable/test”
    android:scaleType=“fitXY”
    Android 学习_第29张图片

  14. 图像视图 ImageView
    图像视图展示的图片通畅位于 res / drawable *** 目录,设置图像视图的显示有两种方法:
    (1)在XML文件中,通过属性android:src设置图片资源,属性值格式: “@drawable/不含扩展名的图片名称”
    (2)在Java代码中,调用setImageResource方法设置图片资源,方法参数格式: “R.drawable.不含扩展名的图片名称”

  15. bug 解决: android studio 中报 Lambda expressions are not supported at language level ‘7’
    在lambda表达式中按 Alt + Enter, 点击 “Set language level to 8 - Lanbdas, type annotations etc.”

  16. 视图滚动
    (1) ScrollView: 它是垂直方向的滚动视图; 垂直方向滚动时,layout_width属性值设置为match_parent, layout_height属性值设置为wrap_content.
    (2) HorizontalScrollView: 它是水平方向的滚动视图; 水平方向滚动时,layout_width属性值设置为wrap_content, layout_height属性值设置为match_parent.

  17. 线性布局的权重 layout_weight
    layout_width 填 0dp 时, layout_weight 表示水平方向的宽度比例.
    layout_height 填 0dp 时, layout_weight 表示垂直方向的高度比例.

  18. 代码中设置视图的宽高
    参考视频

  19. 尺寸
    宽高一般用dp
    文字大小一般用sp
    参考视频
    Android 学习_第30张图片

计算规则
以一个 4.95 英寸 1920 * 1080 的 nexus5 手机设备为例:
Dpi: 
计算直角边(即斜线长)像素数量: 1920^2 + 1080^2 = 2202^2 (勾股定理)
计算 Dpi: 2202 / 4.95 = 445
得到这个设备的Dpi为445 (每英寸的距离中有445个像素)

Density:
上面得到每英寸中有440像素,那么Density为每平方英寸中的像素数量,应该为: 445^2 = 198025

Dip:
所有显示到屏幕上的图像都是以px为单位,Dip是我们开发中使用的长度单位,最后它也需要转换为px,
计算这个设备上 1dip 等于多少px:
px = dip * dpi / 160
根据转换关系:
320 * 480 分辨率,3.6 英寸的手机: dpi为160, 所以在这个设备上: 1dp = 1px

结论:
对于相同分辨率的手机,屏幕越大,同 dp 的组件占用屏幕比例越小.
对于相同尺寸的手机,即使分辨率不同,同 dp 的组件占用屏幕比例也相同.
  1. 设置文本大小
(1) 在Java代码中调用setTextSize方法, 默认单位sp.
(2)XML文件中通过android:textSize指定文本大小,此时需要指定字号单位(不指定会报错).
	px: 它是手机屏幕的最小显示单位,与设备的显示屏有关.
	dp: 它是与设备无关的显示单位,只与屏幕的尺寸有关. 也叫dip.
	sp: 它专门用来设置字体大小,在系统设置中可以调整字体大小.
(3)尺寸解释
	px: px是手机屏幕的最小显示单位,它与设备的显示屏有关.  一般来说,同样尺寸的屏幕(比如6英寸手机), 如果看起来越清晰,则表示像素密度越高,以px计量的分辨率也越大.
	dp: dp 有时也写作dip,指的是与设备无关的显示单位,它只与屏幕的尺寸有关.  一般来说,同样尺寸的屏幕以dp计算的分辨率是相同的,比如同样是6英寸手机,无论它由哪个厂家生产,其分辨率换算成dp单位都是一样大小.
	sp: sp的原理跟dp差不多,但它专门用来设置字体大小. 手机在系统设置里可以调整字体的大小.  设置普通字体时,同数值dp和sp的文字看起来一样大; 如果设置为大字体,用dp设置的文字没有变化,用sp设置的文字就变大了.   字体大小采用不同单位的话,显示的文字大小各不相同. 例如,30px、30dp、30sp这3个字号,在不同手机上显示大小有所差异.  有的手机像素密度较低,一个dp相当于两个px,此时30px等同于15dp; 有的手机像素密度较高,一个dp相当于3个px,此时30px等同于10dp.  假设某个 App 的内部文本使用字号30px, 该 App 安装到前一部手机的字体大小为15dp,安装到后一部手机的字体大小为10dp, 显然后一部手机显示的文本会更小.
  1. Bug解决: “ERROR: Unable to start the daemon process. This problem might be caused by …”
    (1) 修改项目中gradle.properties文件,只要添加以下一行代码: org.gradle.jvmargs=-Xmx512m
    (2) 重启Android Studio

  2. SharedPreference 共享参数用法
    SharedPreference 是 Android 的一个轻量级存储工具, 采用的存储结构是Key-Value的键值对方式.
    共享参数的存储介质是符合XML规范的配置文件. 保存路径是: /data/data/应用包名/shared_prefs/文件名.xml

  3. 利用元数据配置快捷菜单
    (1)元数据的meta-data标签除了name属性和value属性,还拥有resource属性,该属性可指定一个XML文件,表示元数据想要的复杂信息保存于XML数据之中.
    (2)利用元数据配置快捷菜单的步骤如下所示:
    在res/values/strings.xml添加各个菜单项名称的字符串配置
    创建res/xml/shortcuts.xml,在该文件中填入各组菜单项的快捷方式定义(每个菜单对应哪个活动页面)
    给activity节点注册元数据的快捷菜单配置.

  4. 在代码里面设置启动标志
    Intent.FLAG_ACTIVITY_NEW_TASK: 开辟一个新的任务栈
    Intent.FLAG_ACTIVITY_SINGLE_TOP: 当栈顶为待跳转的活动实例时,则重用栈顶的实例
    Intent.FLAG_ACTIVITY_CLEAR_TOP: 当栈中存在待跳转的活动实例时,则重新创建一个新实例,并清除原实例上方的所有实例
    Intent.FLAG_ACTIVITY_NO_HISTORY: 栈中不保存新启动的活动实例
    Intent.FLAG_ACTIVITY_CLEAR_TASK: 跳转到新页面时,栈中的原有实例都被清空

  5. Android生命周期详解
    onCreate: 创建活动. 把页面布局加载进内存,进入了初始状态.
    onStart: 开始活动. 把活动页面显示在屏幕上,进入了就绪状态.
    onResume: 恢复活动. 活动页面进入活跃状态,能够与用户正常交互,例如允许响应用户的点击动作、允许用户输入文字等等.
    onPause: 暂停活动. 页面进入暂停状态,无法与用户正常交互.
    onStop: 停止活动. 页面将不在屏幕上显示.
    onDestroy: 销毁活动. 回收活动占用的系统资源,把页面从内存中清除.
    onRestart: 重启活动. 重新加载内存中的页面数据.
    onNewIntent: 重用已有的活动实例.
    参考文章
    Android 学习_第31张图片

  6. Activity的启动和结束
    从当前页面跳到新页面:
    startActivity(new Intent(源页面.this, 目标页面.class));
    从当前页面回到上一个页面,相当于关闭当前页面,返回代码如下:
    finish(); // 结束当前的活动页面

  7. 按钮控件有两种常用的监听器
    点击监听器,通过setOnClickListener方法设置. 按钮被按住少于500毫秒时,会触发点击事件.
    长按监听器,通过setOnLongClickListener方法设置. 按钮被按住超过500毫秒时,会触发长按事件.

  8. 视图对齐方式
    设置视图对齐方式有两种途径:
    layout_gravity: 它指定当前视图相对于上级视图的对齐方式
    gravity: 它指定下级视图相对于当前视图的对齐方式

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    android:background="#ffff99"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_gravity="bottom"
        android:layout_margin="10dp"
        android:layout_weight="1"
        android:background="#ff0000"
        android:gravity="left"
        android:padding="10dp">

        <View
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#00ffff"></View>
    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_margin="10dp"
        android:layout_weight="1"
        android:background="#ff0000"
        android:gravity="right|bottom"
        android:padding="10dp">
        
        <View
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#00ffff"></View>
    </LinearLayout>
</LinearLayout>
  1. 视图的宽高
    视图宽度 android:layout_width , 视图高度 android:layout_height
    宽高的取值主要有以下三种:
    (1)match_parent: 表示与上级视图保持一致
    (2)match_content: 表示与内容自适应
    (3)以dp为单位的具体尺寸

  2. 完整的页面创建过程包括三个步骤:
    (1)在layout目录下创建XML文件
    (2)创建与XML文件对应的Java代码
    (3)在AndroidManifest.xml中注册页面配置

  3. Activity
    Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务.

  4. Gradle
    Gradle是一个项目自动化构建工具,帮我们做了依赖、打包、部署、发布、各种渠道的差异管理等工作.

  5. App工程目录结构
    App工程分为两个层次,第一个层次是项目,另一个是模块.
    模块依附于项目,每个项目至少有一个模块,也能拥有多个模块.
    一般说的"编译运行App"值得是运行某个模块,而非运行某个项目,因为模块才对应实际的App.

  6. Android采用Log工具打印日志,它将各类日志划分为五个等级
    Log.d: 表示调试信息,可把程序运行时的变量值打印出来,方便跟踪调试. (用的最多)
    Log.e: 表示错误信息,比如可能导致程序崩溃的异常.
    Log.w: 表示警告信息.
    Log.i: 表示一般信息.
    Log.v: 表示冗余信息.

  7. SDK
    Software Development Kit 软件开发工具包,它可将App源码编译为可执行的App应用

  8. Android主要版本发布时间
    Android 学习_第32张图片

  9. Android Studio 中的快捷键

Ctrl + Alt + L 代码格式化
Ctrl + Shift + Enter键 快速开启下一行进行编辑
Alt + Enter 引入包
Ctrl + O 快捷生成内部类
Ctrl + / 单行注释
Ctrl + Shift + / 多行注释
连按两下shift键进行搜索查询
Ctrl + Alt + F 点回车,快速私有化全局变量
Ctrl + Shift + R 批量替换

Jetpack 篇

参考视频
参考介绍链接

1.什么是Jetpack
Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法,减少样板代码,并编写
可在各种Android版本和设备中一致运行的代码,让开发者精力集中编写重要的代码.

2.为什么要使用Jetpack
Android 学习_第33张图片

Java 篇

  1. 多态

一、抽象类和抽象方法
● 抽象类: 抽象类中可以没有抽象方法, 抽象类不能实例化对象.
public abstruct class Pet {
// 每个子类的实现不同
public void shout () {}
}
● 抽象方法: 抽象方法不能实现,因为不是具体的方法,直接以分号结束,不能有{}方法体,没有实现.

  • 抽象方法所在的类必须是抽象类.
  • 抽象类要求继承它的子类必须实现抽象方法,如果没有实现,要求该子类也必须加abstruct修饰.
  • public abstruct viod shout(); // 没有实现体

二、多态的引入
开闭原则: 对扩展开放,对修改关闭.
多态: 针对子类的不同实现对象,针对同一个方法,表现不一样.
同一个引用类型,使用不同的实例,而执行不同操作.即父类引用指向不同子类对象.
三、重写
● 子类要重写的方法必须和父类或接口里面的方法名完全一样.
● 子类要重写的方法必须和父类或接口里面的参数的类型,个数,顺序完全相同.
● 子类要重写的方法返回值类型至少要比父类或者接口更加严格.
四、方法重载和方法重写
Android 学习_第34张图片
五、static
Android 学习_第35张图片
public class MyMath {
// number被static修饰之后,就可以通过 MyMath.number 直接获取了.
// 没有用static修饰的话,就需要new MyMath()创建一个实例化才能访问.
public static int number = 10;
}
static修饰的方法:
示例:
int[] arr = {1,3,2,5,4};
Arrays.sort(arr);
Android 学习_第36张图片

静态代码块,只执行一次,优于方法之前执行. 比如数据库连接,io下载:
Android 学习_第37张图片
六、final
◆ 用final修饰的类不能被继承,例如 String 这个类使用final修饰的,所以String是不能被继承的.
◆ 用final修饰的方法不能被重写.
◆ 在Java里面使用 static final 修饰的变量称为 常量,不能被修改,必须有初始值. 尽量都写成大写的.
七、接口
特点:
▪ 接口是完全抽象的.
▪ 接口是一套规范.
▪ 接口里面定义的字段属性全是常量, 默认加 public static final 修饰.
▪ 接口定义的方法全是抽象方法, 默认都有 public abstruct 修饰.
▪ 接口可以充分解耦合,所以有面向接口编程.
▪ 一个子类可以实现多个接口,却只能继承一个父类.
▪ 接口可以继承接口,接口不能继承类.
Android 学习_第38张图片
八、如何实现多态
Android 学习_第39张图片
满足多态三要素:
▪ 继承父类或者实现接口
▪ 子类重写父类或接口里面的抽象方法
▪ 父类或接口引用指向子类实例化的对象

  1. 继承 (解决重用的问题)

(1) 继承中访问修饰符
Android 学习_第40张图片
(2) 不能被继承的父类资源: private成员,构造方法.
(类中加了有参数的构造方法后,无参构造方法也是必须保留的,这样才是一个完整的类)
(3) super
super表示父类的对象,super()只能在子类构造方法里面才能出现,而且必须放在第一行.
super() 表示调用父类无参构造方法
super(name) 表示调用父类带一个name的构造方法.
(4) 执行顺序,后面执行的可能会覆盖前面的值
子类构造方法 => 父类构造方法 => 父类属性赋初始值 => 子类属性赋初始值
(5) 如果一个类没有显示继承,都默认继承Object类.
(6) Java里面是单继承,只能继承一个父类.

  1. Java面向对象三个特征

(1) 封装
面向对象语言中,我们操作的是一个又一个对象。这些对象的数据与操作数据的方法会被封装到特定的类里面,我们在使用的时候不需要关心该对象的某些方法是如何实现的,只需要调用类提供的接口即可使用这些方法。这就是封装的含义。
(2) 继承
当一个类是另一个类的特例时,我们可以让这个特例的类去继承另一个类,这样,这个特例的类被称作子类,而继承的类被称作父类。这样子类不仅能有父类的特性,还可以有自己的额外扩展,这就是继承的含义。
(3) 多态
多态的含义可以表达为“对外提供一个接口,内部可以有多种实现”。

  1. Java中的类和对象
    参考链接
    类:
    (1) 创建类后没有手动添加构造方法时,系统默认有一个没有参数的构造方法.
    (2) 当给类手动添加构造方法后,默认无参的构造方法将不存在,需要我们手动添加一个无参的构造方法.

  2. 堆栈相关知识
    参考视频

  3. Java 八种基本数据类型
    又可以分成四个大类:
    (1) 整型: byte, short, int, long
    (2) 浮点型: float, double
    (3) 字符型: char
    (4) 布尔型: boolean
    (PS: 引用数据类型主要有: 数组(类型),类(类型),接口(类型),包装类型.)
    Android 学习_第41张图片

  4. JavaBean的概念

JavaBean 是一个公共的(public)JavaBean 有一个不带参数的构造方法
JavaBean 通过setXXX方法设置属性,通过getXXX方法获取属性

典型JavaBean 实例:
public class CounterBean{
	private int count = 0;
	public CounterBean(){ }
	public int getCount(){
		return count;
	}
	public void setCount(int count){
		this.count = count;
	}
}
  1. Java中拆箱与装箱
自动装箱: 指开发人员可以把一个基本数据类型直接赋给对应的包装类.
自动拆箱: 指开发人员可以把一个包装类对象直接赋给对应的基本数据类型.

典型应用:
List list = new List();
list.add(1); //加的是整型的对象
int j = (Integer) list.get(0);

Integer i = 1; //装箱
int j = i; //拆箱
  1. 一些词语解释

GUI: 图形化界面(Graphical User Interface)
CLI: 命令行方式(Command Line Interface)
JRE(Java Runtime Enviroment): Java运行环境
JDK(Java Development Kit): Java 开发工具包
IDE (Integrated Development Environment): 集成开发环境
API (Application Programming Interface): 应用程序编程接口
OOP(Object Oriented Programming): 面向对象程序设计
AOP(Aspect Oriented Programming): 面向切面编程

你可能感兴趣的:(android,android,studio,ide)