Android 学习

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. 函数头
    在这里插入图片描述

  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 介绍
    在这里插入图片描述

  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<List>() { }.getType();
    Type type = new TypeToken<Map>() { }.getType();
    Type type = new TypeToken<Set>() { }.getType();

  9. Retrofit 注解
    在这里插入图片描述

  10. Retrofit
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

  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请求
    在这里插入图片描述
// 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);

在这里插入图片描述

  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 生命周期
    在这里插入图片描述

  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
    在这里插入图片描述

  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. 补间动画
    在这里插入图片描述

  9. 动画启动和停止
    在这里插入图片描述

  10. 动画
    在这里插入图片描述

  11. ListView
    参考视频

  12. RelativeLayout, TableLayout, GridLayout
    参考视频

  13. LinearLayout
    在这里插入图片描述

  14. 分割线

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@color/purple_500"></View>
  1. PopupWindow
    在这里插入图片描述

  2. AlertDialog
    在这里插入图片描述

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

  4. Notification
    参考视频

  5. ProgressBar
    在这里插入图片描述

  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>

在这里插入图片描述
在这里插入图片描述

  1. EditText
    在这里插入图片描述

  2. 实现跑马灯效果
    需要添加焦点才能自动跑起来
    在这里插入图片描述

  3. TextView 带阴影
    在这里插入图片描述

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

  5. 向上一个Activity返回数据
    在这里插入图片描述

  6. Bundle
    在这里插入图片描述

  7. 向下一个Activity发送数据
    在这里插入图片描述

  8. 隐式Intent
    在这里插入图片描述

  9. Intent的组成部分
    在这里插入图片描述

  10. 各状态之间的切换过程
    在这里插入图片描述

  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”
    在这里插入图片描述

  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
    参考视频
    在这里插入图片描述

计算规则
以一个 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: 重用已有的活动实例.
    参考文章
    在这里插入图片描述

  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主要版本发布时间
    在这里插入图片描述

  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
在这里插入图片描述

Java 篇

  1. 多态

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

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

二、多态的引入
开闭原则: 对扩展开放,对修改关闭.
多态: 针对子类的不同实现对象,针对同一个方法,表现不一样.
同一个引用类型,使用不同的实例,而执行不同操作.即父类引用指向不同子类对象.
三、重写
● 子类要重写的方法必须和父类或接口里面的方法名完全一样.
● 子类要重写的方法必须和父类或接口里面的参数的类型,个数,顺序完全相同.
● 子类要重写的方法返回值类型至少要比父类或者接口更加严格.
四、方法重载和方法重写
在这里插入图片描述
五、static
在这里插入图片描述
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);
在这里插入图片描述

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

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

(1) 继承中访问修饰符
在这里插入图片描述
(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: 引用数据类型主要有: 数组(类型),类(类型),接口(类型),包装类型.)
    在这里插入图片描述

  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): 面向切面编程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值