IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android笔记---十万字符---超全 -> 正文阅读

[移动开发]Android笔记---十万字符---超全

Android

文章目录


书上的 2 3 4 5 6章

布局2

控件3

活动4:启动新activity 相互传参

数据存储5 listview 数据库 和 记事本差不多

连接木木数据库

adb connect 127.0.0.1:7555
<Button
        		属性
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button6"
                android:layout_marginTop="120dp"           >
   	内容:最小单位自然没有
</Button> 
    <LinearLayout
                  属性
        android:orientation="vertical"  布局方式
        android:background="#ffffaa"    背景色
        android:layout_width="match_parent"		
        android:layout_height="match_parent">
        以下是嵌套的内容
        <Button
            androidlayout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button1"
            ></Button>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button2"
            ></Button>
    </LinearLayout>

零、零碎

0.1 横竖屏

在配置文件中的某个Activity的属性中设置:

竖屏:android:screenOrientation="portrait"
横屏:android:screenOrientation="landscape"

0.2 标题

设置Activity在手机上的标题

android:label="名称"

一、View视图

布局通用属性:

属性名称功能细节
id唯一标识“@+id/***”
layout_widthwrap_content正好包裹内容
match_parent与父容器宽(高)相同
layout_height同上
background背景色
layout_margin与屏幕或者其他
控件
的距离
layout_marginTop 与上面
layout_marginLeft 与左面
layout_marginBottom 与下面
layout_marginEnd 感觉和Right差不多
layout_marginRight
padding与内部控件的距离也是有一些细节,与上面类似

1.1 相对布局-RelativeLayout

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRPBMuvo-1625377200724)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319193611617.png)]

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout // 相对布局
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button1"
        android:text="123"
        android:textSize="20pt"
        android:layout_alignParentBottom="true" 	// 最下面
        android:layout_marginBottom="20dp"			// 与下面距离20dp
        ></Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20pt"
        android:id="@+id/button2"
        android:text="465"
        android:layout_centerHorizontal="true"		// 水平居中
        android:layout_marginTop="260dp"			// 距离上面260dp
        ></Button>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="789"
        android:textSize="20pt"
        android:id="@+id/button3"
        android:layout_alignBottom="@id/button2"	// 相对 2 底部对齐
        android:layout_marginBottom="100dp"			// 距离 2 底部100dp
        android:layout_toRightOf="@id/button2"		// 在 2 的右边
        ></Button>

</RelativeLayout>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yqawJEbm-1625377200726)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319194707387.png)]

1.2 线性布局-LinearLayout

主要是两个:

orientation布局内部空间的排列方式
vertical垂直布局
horizontal水平布局
layout_weight权重 多个控件根据权重分配所占空间的比例

如果是垂直布局,那么控件的就应该是0px

如果是水平布局,那么控件的就应该是0px

可以直接用布局样例进行嵌套

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">


    <LinearLayout
        android:orientation="vertical"
        android:background="#ffffaa"
        android:layout_width="0dp"			
        android:layout_height="match_parent" // 注意:这里需要是全部撑开的 (不过貌似也要根据情况)
        android:layout_weight="1" >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button1"
            ></Button>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button2"
            ></Button>
    </LinearLayout>


    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="#00ffff"
        android:layout_weight="2">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:background="#ff00ff"
            >
            <Button
                android:layout_marginLeft="20dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button3"
                ></Button>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button4"
                android:layout_marginLeft="20dp"
                ></Button>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:background="#25ff63"
        >
            <Button
                android:id="@+id/b5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
            android:text="Button5"
                android:layout_marginTop="50dp"
                android:layout_marginLeft="50dp"
                ></Button>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button6"
                android:layout_marginTop="120dp"
            ></Button>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

? [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3uWviAjF-1625377200728)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319201450820.png)]

1.3 表格布局-TableLayout

表格布局属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AOYcURjH-1625377200730)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319203710871.png)]

表格布局控件属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mYI91tM7-1625377200732)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319203838788.png)]

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:shrinkColumns="1" // 用了之后 没发现改变
    android:stretchColumns="0,2" // 拉伸 0 2列的控件
             >

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:text="按钮1"></Button>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="1"
            android:layout_marginLeft="20px"
            android:text="按钮2"></Button>
    </TableRow>

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="1"
            android:text="按钮3"></Button>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="2"
            android:text="按钮4"></Button>
    </TableRow>

    <TableRow>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="2"
            android:text="按钮5"></Button>
    </TableRow>

</TableLayout>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wp4kVXfy-1625377200734)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319204138342.png)]

二、界面控件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jgbfLUZ2-1625377200735)(C:\Users\陌陌\AppData\Roaming\Typora\typora-user-images\image-20210319204644109.png)]

控件名称作用
Text View显示文本(也可以点击)
Button显示文本、图片,支持点击
EditView编辑框 可以输入文字
ImageView
RadioButton
CheckBox
Toast

2.1 Button 事件

在java代码中可以直接连接xml中的控件:

加入需要在java中修改xml的Button控件:

Button java_b = findViewById(R.id.xml_b);
控件类型 Java变量名 = findViewById(R.id. xml的变量名)

1。新建方法

在java代码中新建一个方法,名字无所谓,但需要这样的形式:

public void 方法名(View v){}

在xml中调用此方法:

android:onClick="click"
        <Button
            android:id="@+id/b_iu" 				// 按钮id
            android:layout_width="wrap_content"	
            android:layout_height="wrap_content"
            android:textSize="50dp"
            android:text="旧的文本"				// 文本
            android:onClick="click"				// 对应java中的方法名
            ></Button>
    public void click(View v){
        // 获取界面中的按钮
        Button b_java = findViewById(R.id.b_iu);
        b.setText("新的文本");
    }

2。new一个监听

		Button b2 = findViewById(R.id.b2);
		// 重写
        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        b2.setText("新文本");
                    }
                }
        );
    }

3。实例

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class Activity_Test extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);
        // 方式一 点击 TextView 改变文本文字
        // TextView也是可以点击的·
        TextView java_textView = findViewById(R.id.xml_textView);

        java_textView.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (java_textView.getText().equals("123"))
                            java_textView.setText("321");
                        else
                            java_textView.setText("123");

                    }

                }
        );

        // 方式一 点击Button 改变文本文字
        Button button = findViewById(R.id.button);
        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (java_textView.getText().equals("123"))
                            java_textView.setText("321");
                        else
                            java_textView.setText("123");
                    }
                }
        );
    }


    // 方式二 点击Button改变B按钮文字
    public void click(View v) { // 方法名无所谓
        Button java_button = findViewById(R.id.xml_button);
        if (java_button.getText().equals("来按"))
            java_button.setText("好的");
        else
            java_button.setText("来按");

    }
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
    tools:context=".Activity_Test">

    <TextView
        android:id="@+id/xml_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="123"
        android:textColor="#ff0099"
        android:textSize="50dp"></TextView>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        android:layout_below="@+id/xml_textView"
        android:layout_marginTop="50dp"
        android:layout_centerHorizontal="true"
        android:text="文字变色"></Button>

    <Button
        android:id="@+id/xml_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:onClick="click"
        android:text="来按"

        android:textSize="60dp"></Button>

</RelativeLayout>

2.2 EditText

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LhOtfrCM-1625377200736)(https://z3.ax1x.com/2021/03/29/cC61rd.jpg)]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/edit_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入A">

    </EditText>

    <EditText
        android:id="@+id/edit_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入B"></EditText>

    <Button
        android:id="@+id/b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="和计算"></Button>

    <EditText
        android:id="@+id/edit_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></EditText>

</LinearLayout>

java:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);

        EditText editText_1 = findViewById(R.id.edit_1);
        EditText editText_2 = findViewById(R.id.edit_2);
        EditText editText_sum = findViewById(R.id.edit_3);
        Button button = findViewById(R.id.b);
        
        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String A = editText_1.getText().toString(); // 注意需要toString
                        double a = Double.parseDouble(A);			// 转成Double类型
                        String B = editText_2.getText().toString();	
                        double b = Double.parseDouble(B);
                        double ans = a + b;
                        editText_sum.setText("结果:" + ans);
                    }
                }
        );
    }

2.3 ImageView +Radio + CheckBox

  1. 单选:RadioButton为单选按钮,android:checked属性指定是否选中的状态。

    RadioGroup是单选组合框,可容纳多个RadioButton,并把它们组合在一起,实现单选状态。

    // 获取选中的单选框按钮 使用地址来匹配
    int id = group.getCheckedRadioButtonId();
     if (id == R.id.radio_5){...}
    
  2. 多选:CheckBox表示复选框,它是Button的子类,用于实现多选功能,通过android:checked属性指定CheckBox控件是否选中的状态。

点击切换图片实例:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下面哪个不是🐎?"
        android:textSize="25dp"></TextView>

    <RadioGroup
        android:id="@+id/group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RadioButton
            android:id="@+id/radio_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="白🐎"></RadioButton>

        <RadioButton
            android:id="@+id/radio_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="黑🐎"></RadioButton>

        <RadioButton
            android:id="@+id/radio_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="黄🐎"></RadioButton>

        <RadioButton
            android:id="@+id/radio_4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="笨🐎"></RadioButton>

        <RadioButton
            android:id="@+id/radio_5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="斑🦓"></RadioButton>

    </RadioGroup>

    <Button
        android:id="@+id/b2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="选了啥?"></Button>

    <ImageView
        android:id="@+id/icon_dui"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/ooo"></ImageView>


</LinearLayout>
 Button b2 = findViewById(R.id.b2);
        RadioGroup group = findViewById(R.id.group);
        ImageView image_dui = findViewById(R.id.icon_dui);

        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // 获取选的按钮
                        int id = group.getCheckedRadioButtonId();
                        // 对比资源地址
                        if (id == R.id.radio_5) {
                            Toast.makeText(Activity_Test.this,   "你选了🦓", Toast.LENGTH_SHORT).show();
                            // 重新设置图片
                            image_dui.setImageResource(R.drawable.kkkk);
                        } else {
                            image_dui.setImageResource(R.drawable.ooo);
                            Toast.makeText(Activity_Test.this, "你选了🐎", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
        );

2.4 Toast

Toast.makeText(Activity_Test.this, "你选了🦓", Toast.LENGTH_SHORT).show();

解释:Toast.makeText( 一个Activity(Java), "内容", 出现位置).show();

2.5 AlertDialog

cCoRK0.png

1. 简单Dialog

基本设置:

AlertDialog.Builder builder = new AlertDialog.Builder(Activity_Test.this)
                                .setTitle("标题")
                                .setMessage("内容-内容-内容")  // 主窗口内容 还可以设置其他内容
                                .setPositiveButton("积极", null) // null这里可以设置出发的事件
                                .setNegativeButton("消极", null);
                        AlertDialog dialog = builder.create(); // 使用这个属性来创建
                        dialog.show();

实例代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮"></Button>
</LinearLayout>
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);

        Button b = findViewById(R.id.b);
        b.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(Activity_Test.this)
                                .setTitle("标题")
                                .setMessage("内容-内容-内容")  // 主窗口内容 还可以设置其他内容
                                .setPositiveButton("积极", null) // null这里可以设置出发的事件
                                .setNegativeButton("消极", null);
                        AlertDialog dialog = builder.create(); // 使用这个属性来创建
                        dialog.show();
                    }
                }
        );

    }

2. 带有单选的Dialog

 <TextView
        android:layout_centerHorizontal="true"
        android:id="@+id/tttt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"

        android:text="111111111111"></TextView>

    <Button
        android:id="@+id/b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮"></Button>
int size = 1; // 全局变量

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);

        Button b = findViewById(R.id.b);
        String[] s = {"small", "medium", "big"};
        TextView tt = findViewById(R.id.tttt);
        tt.setText("565646");
        b.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(Activity_Test.this)
                                .setTitle("选择字号")
                                .setSingleChoiceItems(s, size, new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        size = which;
                                    }
                                })
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        tt.setText(size + "");
                                        tt.setTextSize(size * 8 + 12);
                                    }
                                })
                                .setNegativeButton("取消", null);
                        AlertDialog dialog = builder.create();
                        dialog.show();
                    }
                }
        );
    }

2.6 ListView

1. 含义

需要3个东东:

  1. 数据源

  2. 布局——item layout 项布局

  3. Adapter

  4. 资源

	String[] sName = {"物品1", "物品2", "物品3", "物品4", "物品5", "物品6"};
    String[] sMoney = {"1元", "1元", "1元", "1元", "1元", "1元"};
    int[] images_Address = {R.drawable.apple, R.drawable.cake, R.drawable.table, R.drawable.wireclothes,
            R.drawable.kiwifruit, R.drawable.scarf};
// 图片都是资源,资源用int型地址表示

2.新建一个xml,专门作为项布局

就是做中的一个项的大概的布局样式

然后动态添加修改资源

cAr5NR.md.jpg

这个布局运行起来不和完成图中一样,因为视图大小不一样。放到ListView中会压缩的。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/it"
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:src="@drawable/table"></ImageView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">
        <TextView
            android:id="@+id/shop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="这个是一个商品"
            android:textColor="#ff66ff"
            android:textSize="60px"></TextView>
        <TextView
            android:id="@+id/money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="12块钱"
            android:textSize="60px"></TextView>
    </LinearLayout>
</LinearLayout>

3.适配器设置:

在java主类中新建一个类:继承至BaseAdapter,然后实现功能。

class Adapter_T extends BaseAdapter {
    	// 下面的三个貌似用不到,但是必须要设置返回内容
        @Override
        public int getCount() {
            return 6;
        }
        @Override
        public Object getItem(int position) {
            return sName[position];
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 第一行是确定的
            View v = View.inflate(MainActivity.this, R.layout.shop_item, null);
            // 下面是项布局中的控件 
            // 对每个控件实现修改,这样就形成了动态
            ImageView imageView = v.findViewById(R.id.it);
            TextView money = v.findViewById(R.id.money);
            TextView shopT = v.findViewById(R.id.shop);
            imageView.setImageResource(images_Address[position]);
            money.setText(sMoney[position]);
            shopT.setText(sName[position]);
            // 注意需要返回v
            return v;
        }
    }

最后,在主方法中调用就可以了:

		ListView listView = findViewById(R.id.lll);
        Adapter_T adapter_t = new Adapter_T();
        listView.setAdapter(adapter_t);

2. 代码

xml

<?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="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/lll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>


</LinearLayout>

项布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/it"
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:src="@drawable/table"></ImageView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">
        <TextView
            android:id="@+id/shop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="这个是一个商品"
            android:textColor="#ff66ff"
            android:textSize="60px"></TextView>
        <TextView
            android:id="@+id/money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="12块钱"
            android:textSize="60px"></TextView>
    </LinearLayout>
</LinearLayout>

java:


public class MainActivity extends AppCompatActivity {
    String[] sName = {"物品1", "物品2", "物品3", "物品4", "物品5", "物品6"};
    String[] sMoney = {"1元", "2元", "3元", "4元", "5元", "6元"};
    int[]    images_Address = {R.drawable.apple, R.drawable.cake, R.drawable.table, R.drawable.wireclothes,R.drawable.kiwifruit, R.drawable.scarf};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = findViewById(R.id.lll);
        Adapter_T adapter_t = new Adapter_T();
        listView.setAdapter(adapter_t);

    }

    class Adapter_T extends BaseAdapter {
        @Override
        public int getCount() {
            return 6;
        }
        @Override
        public Object getItem(int position) {
            return sName[position];
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = View.inflate(MainActivity.this, R.layout.shop_item, null);
            ImageView imageView = v.findViewById(R.id.it);
            TextView money = v.findViewById(R.id.money);
            TextView shopT = v.findViewById(R.id.shop);
            imageView.setImageResource(images_Address[position]);
            money.setText(sMoney[position]);
            shopT.setText(sName[position]);
            return v;
        }
    }
}

三、Activity

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2iW24yiX-1625377200740)(https://z3.ax1x.com/2021/04/12/cD0Dwn.md.png)]

3.0 请求码和结果码

请求码和结果码的作用

请求码:

例如请求页面有多个button,根据请求码就知道是哪个button在请求

结果码:

多个请求可以打开多个页面,根据结果码就知道我们打开的是哪个界面

*请求码是用来标识请求源的,结果码是用来标识结果源的。*

两个不错的博客:

传送门-有实例

传送门-理论多

3.1 open another activity

Intent intent = new Intent(当前activity.this, 要打开的activity.class);

关闭当前activity

 activity.this.finish();
Button b = findViewById(R.id.b);
        b.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(Activity_Test.this, MainActivity.class);
						Intent intent = new Intent(当前activity.this, 要打开的activity.class);
          
                        startActivity(intent);
                    }
                }
        );

3.2 intent - 传输数据

Intent intent = new Intent(Activity_Test.this, MainActivity.class);
intent.putExtra("animal", "🐂");
intent.putExtra("digit", 1);
intent.putExtra("只能字符串", "都可以");

接收数据:

Intent intent = getIntent();
String animal = intent.getStringExtra("animal");
int res = intent.getIntExtra("digit",0); // 如果是int型的 

样例1:选动物🐂🐎🦓

注意:有三张图片

思路:在主java获取图片的地址,并向副传输三个信息:选择文本、图片地址、介绍文本。

主界面xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="窗口一:你喜欢下面哪个动物?"
        android:textSize="100px"></TextView>

    <Button
        android:id="@+id/b1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="马🐎"
        android:textSize="50px"></Button>

    <Button
        android:id="@+id/b2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="斑马🦓"
        android:textSize="50px"></Button>

    <Button
        android:id="@+id/b3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="牛🐂"
        android:textSize="50px"></Button>


</LinearLayout>

主界面java

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.zip.CheckedOutputStream;

public class Activity_Test extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);

        Button b1 = findViewById(R.id.b1);
        Button b2 = findViewById(R.id.b2);
        Button b3 = findViewById(R.id.b3);
        Intent intent = new Intent(Activity_Test.this, MainActivity.class);
        b1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        intent.putExtra("animal", "🐎");
                        intent.putExtra("tu", R.drawable.ma);
                        intent.putExtra("jS", "我是一只马");
                        startActivity(intent);
                    }
                }
        );
        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        intent.putExtra("animal", "🦓");
                        intent.putExtra("tu", R.drawable.banma);
                        intent.putExtra("jS", "我是一只斑马");
                        startActivity(intent);

                    }
                }
        );
        b3.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        intent.putExtra("animal", "🐂");
                        intent.putExtra("tu", R.drawable.niu);
                        intent.putExtra("jS", "我是一只牛");
                        startActivity(intent);
                    }
                }
        );
    }


}

副界面xml:

<?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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="窗口二: 我喜欢"
        android:textSize="100px"></TextView>

    <TextView
        android:id="@+id/likeText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="默认文字"
        android:textColor="@color/design_default_color_primary_dark"
        android:textSize="50dp"></TextView>

    <ImageView
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@drawable/niu"></ImageView>

    <TextView
        android:id="@+id/jS"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="介绍:"
        android:textSize="30dp"></TextView>

</LinearLayout>

副界面java

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.companion.WifiDeviceFilter;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = getIntent();
        int res = intent.getIntExtra("tu",0);
        String animal = intent.getStringExtra("animal");
        String js = intent.getStringExtra("jS");

        ImageView imageView = findViewById(R.id.image);
        TextView textView = findViewById(R.id.likeText);
        TextView jS = findViewById(R.id.jS);
        imageView.setImageResource(res);
        jS.setText(js);
        textView.setText(animal);
    }


}

3.3 回传

  1. 主界面java:

使用startActivityForResult方法开启
1个参数是Intent对象,第2个参数是请求码,用于标识请求的来源

     Intent intent = new Intent(MainActivity.this,SecondActivity.class);
	 startActivityForResult(intent,1);
  1. 副界面java:

使用setResult(1,intent) 第1个参数是请求码,和主界面java的对应即可

		Intent intent = new Intent();
        intent.putExtra("data","Hello MainActivity");
        setResult(1,intent);
        finish();

  1. 主界面java:

重写onActivityResult方法

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    
    // 数据在data中 之后处理数据就可以了
    if (requestCode == 1&&resultCode == 2){ // 不知道这俩是啥意思
        String acquiredData= data.getStringExtra("data"); //获取回传的数据
        Toast.makeText(MainActivity.this,acquiredData,Toast.LENGTH_SHORT).show();
    }
}

样例2:是否买动物

[![cDB6HA.md.jpg](https://z3.ax1x.com/2021/04/12/cDB6HA.md.jpg)](https://imgtu.com/i/cDB6HA)
[![cDByBd.md.jpg](https://z3.ax1x.com/2021/04/12/cDByBd.md.jpg)](https://imgtu.com/i/cDByBd)

主界面xml:

同样例1

主界面java

package com.example.test;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.zip.CheckedOutputStream;

public class Activity_Test extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);

//        获取三个按钮
//        每个按钮是一个动物 都会跳转到副界面
        Button b1 = findViewById(R.id.b1);
        Button b2 = findViewById(R.id.b2);
        Button b3 = findViewById(R.id.b3);
        b1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Send("🐎", R.drawable.ma, "我是一只马");
                    }
                }
        );
        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Send("🦓", R.drawable.banma, "我是一只斑马");
                    }
                }
        );
        b3.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Send("🐂", R.drawable.niu, "我是一只牛");
                    }
                }
        );

    }
//    自建方法:发送三种数据:显示内容 图片地址 显示介绍
//    然后用的是可以接受返回数据的方法
    void Send(String a, int b, String c) {
        Intent intent = new Intent(Activity_Test.this, MainActivity.class);
        intent.putExtra("animal", a);
        intent.putExtra("tu", b);
        intent.putExtra("jS", c);
        startActivityForResult(intent, 1);
    }
//    重写接受返回数据方法
//    接受数据的使用和在副界面上一样
//    然后处理数据就行了
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String r = data.getStringExtra("B");
        if(r.equals("Yes"))
            Toast.makeText(Activity_Test.this, "Buy it", Toast.LENGTH_SHORT).show();
        else if(r.equals("No"))
            Toast.makeText(Activity_Test.this, "Don't but it", Toast.LENGTH_SHORT).show();
        else
            Toast.makeText(Activity_Test.this, "错", Toast.LENGTH_SHORT).show();
    }
}

副界面xml

<?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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="窗口二: 我喜欢"
        android:textSize="100px"></TextView>

    <TextView
        android:id="@+id/likeText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="默认文字"
        android:textColor="@color/design_default_color_primary_dark"
        android:textSize="50dp"></TextView>

    <ImageView
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@drawable/niu"></ImageView>

    <TextView
        android:id="@+id/jS"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="介绍:"
        android:textSize="30dp"></TextView>

    <Button
        android:id="@+id/buy1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="buy it"></Button>
    <Button
        android:id="@+id/buy2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="don't buy it"></Button>
</LinearLayout>

副界面java

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.companion.WifiDeviceFilter;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        得到3个需要处理的数据
        Intent intent = getIntent();
        int res = intent.getIntExtra("tu", 0);
        String animal = intent.getStringExtra("animal");
        String js = intent.getStringExtra("jS");
//        对三个数据进行处理
        ImageView imageView = findViewById(R.id.image);
        TextView textView = findViewById(R.id.likeText);
        TextView jS = findViewById(R.id.jS);
        imageView.setImageResource(res);
        jS.setText(js);
        textView.setText(animal);

        Button buy1 = findViewById(R.id.buy1);
        Button buy2 = findViewById(R.id.buy2);
//        是否购买按钮
        buy1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        intent.putExtra("B", "Yes");
//                        回传数据
                        setResult(2, intent);
//                        记得需要终止当前的Activity
                        MainActivity.this.finish();
                    }
                }
        );
        buy2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        intent.putExtra("B", "No");
                        setResult(2, intent);
                        MainActivity.this.finish();
                    }
                }
        );
    }
}

四、数据存储

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i77mPEKq-1625377200741)(https://z3.ax1x.com/2021/04/19/cTAEJf.md.png)]

4.1 文件存储

1. 读

			FileInputStream is = openFileInput("id.dat");
            byte[] buffer = new byte[is.available()];   // is的大小
            is.read(buffer); 							// 读入到字节流
            is.close();									// 关闭读入

2. 写

FileOutputStream fos = openFileOutput(String name, int mode);
FileInputStream fis = openFileInput(String name);


mode取值:
MODE_PRIVATE:该文件只能被当前程序读写一般用这个
MODE_APPEND:该文件的内容可以追加;
MODE_WORLD_READABLE:该文件的内容可以被其他程序读;
MODE_WORLD_WRITEABLE:该文件的内容可以被其他程序写
 			String s = "Hello Word";
			FileOutputStream os = openFileOutput("id.dat", MODE_APPEND);
            os.write(s.getBytes()); 	// 作为字节流写入
            os.close();

样例1:登录界面-保存账号密码

xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:layout_above="@+id/password"
        android:id="@+id/id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="账号:"
        android:textSize="60px"></EditText>

    <EditText
        android:layout_above="@id/b1"
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码:"></EditText>

    <Button
        android:id="@+id/b1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="登录"
        android:textSize="50px"></Button>


</RelativeLayout>
java:
package com.example.test;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Activity_Test extends AppCompatActivity {

    Button re;
    EditText id_text, password_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);
        init();
        re.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (id_text.getText().toString().equals("")) {
                            Toast.makeText(Activity_Test.this, "测试", Toast.LENGTH_SHORT).show();
                            read();
                        } else
                            write();
                    }
                }
        );
    }

    private void init() {
        re = findViewById(R.id.b1);
        id_text = findViewById(R.id.id);
        password_text = findViewById(R.id.password);
    }

    private void read() {
        FileInputStream is;
        try {
            is = openFileInput("id.dat");
            byte[] buffer = new byte[is.available()];
            is.read(buffer);
            String[] data = (new String(buffer)).split(",");
            String id = data[0];
            String pas = data[1];
            id_text.setText(id);
            password_text.setText(pas);
            is.close();
            Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void write() {
        String id = id_text.getText().toString();
        String pas = password_text.getText().toString();
        String s = id + "," + pas;
        FileOutputStream os;
        try {
            os = openFileOutput("id.dat", MODE_APPEND);
            os.write(s.getBytes());
            os.close();
            Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.2 SharedPreferences

SharedPreferences:是Android平台上一个轻量级的存储类,用于程序中一些少量数据持久化存储。

存储的数据是键值对的形式

1. 读


SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE); // 获取SharedPreferences实例对象
SharedPreferences.Editor editor = sp.edit(); 					  // 获取编辑器
editor.putString("name", "传智播客");              				   // 存入String类型数据
editor.putInt("age", 8);                                       	  // 存入int类型数据
editor.commit(); 												  // 提交数据

2. 写


SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE); // 获取SharedPreferences实例对象
String data= sp.getString("name","[null]");						  // 获取以name为键的值 如果没有 则返回[null]           

3.清除数据

editor.remove("name");      // 一个数据
editor.clear();             // 全部数据

样例2:登录界面-可判断账号密码对错

xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:layout_above="@+id/password"
        android:id="@+id/id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="账号:"
        android:textSize="60px"></EditText>

    <EditText
        android:layout_above="@id/b1"
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码:"></EditText>

    <Button
        android:id="@+id/b1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="登录"
        android:textSize="50px"></Button>
    <Button
        android:layout_below="@id/b1"
        android:id="@+id/b2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="注册"
        android:textSize="50px"></Button>


</RelativeLayout>
java:
package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class Activity_Test extends AppCompatActivity {

    Button reg, sign;
    EditText id_text, password_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);
        init();
        reg.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        write_2();
                    }
                }
        );
        sign.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        read_2();
                    }
                }
        );
    }
    private void init() {
        sign = findViewById(R.id.b1);
        reg = findViewById(R.id.b2);
        id_text = findViewById(R.id.id);
        password_text = findViewById(R.id.password);
    }

    private void read_2() {
        SharedPreferences sp = getSharedPreferences("data", MODE_PRIVATE);
        String id = id_text.getText().toString();
        String pas_Real = sp.getString(id, "null");
        String pas = password_text.getText().toString();
        if (pas_Real == "null")
            Toast.makeText(this, "用户名不正确", Toast.LENGTH_SHORT).show();
        else if (pas.equals(pas_Real) == false)
            Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
        else
            Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
    }

    private void write_2() {
        SharedPreferences sp = getSharedPreferences("data", MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        String id = id_text.getText().toString();
        String pas = password_text.getText().toString();
        editor.putString(id, pas);
        editor.commit();
        Toast.makeText(this, "注册 成功", Toast.LENGTH_SHORT).show();
    }
}

4.3 SQLite数据库

SQLite是Android自带的一个轻量级的数据库,他运算速度快,占用资源少,支持基本SQL语法。

SQLite数据库可以存储应用程序中的大量数据,并对数据进行管理和维护。

注意:需要创建一个数据库类,继承自SQLiteOpenHelper,它是一个抽象类。需要实现两个普通方法和一个构造方法。

1. 创建数据库类

public class MyDbHealper extends SQLiteOpenHelper {
	// Context 是一个Activity
    public MyDbHealper(Context context) {
        super(context, "friend.db", null, 1);
        
        super(上下文, 数据库名字, 游标工厂, 数据库版本);
    }
	
    // 第一次创建时自动调用
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE  people(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(20), phone varchar(20))";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

2. 操作数据库

//  	是自己定义的方法
    private void execute(String sql, Object[] args) {
//      新建数据库帮助类
        MyDbHealper healper = new MyDbHealper(Activity_Test.this);
//      获取数据库对象
        SQLiteDatabase db = healper.getWritableDatabase();
//      执行数据库语句
        db.execSQL(sql, args);
//      关闭数据库
        db.close();
    }

3. 样例3:通讯录+模糊查询

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cj30KHpt-1625377200742)(https://z3.ax1x.com/2021/05/10/gNKwHe.png)]

xml
<?xml version="1.0" encoding="utf-8"?><!--<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"-->
<!--    android:layout_width="match_parent"-->
<!--    android:layout_height="match_parent"-->
<!--    android:orientation="vertical">-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/id"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true"
        android:hint="name"></EditText>

    <EditText
        android:id="@+id/phone"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/id"
        android:layout_centerInParent="true"
        android:hint="phone"></EditText>

    <EditText
        android:id="@+id/likeText"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="模糊查询name"
        android:layout_below="@+id/phone"
        android:layout_centerInParent="true"
        ></EditText>

    <Button
        android:id="@+id/b_insert"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/likeText"
        android:layout_marginRight="20dp"
        android:layout_toLeftOf="@+id/b_delete"
        android:text="Insert"></Button>

    <Button
        android:id="@+id/b_delete"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/likeText"
        android:layout_centerInParent="true"
        android:text="DELETE"></Button>

    <Button
        android:id="@+id/b_update"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/likeText"
        android:layout_marginLeft="20dp"
        android:layout_toRightOf="@id/b_delete"
        android:text="UPDATE"></Button>

    <Button
        android:id="@+id/b_Select"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/b_insert"
        android:layout_alignLeft="@+id/b_insert"
        android:layout_marginTop="10dp"
        android:text="select"></Button>

    <Button
        android:id="@+id/b_Search"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/b_delete"
        android:layout_alignRight="@+id/b_update"
        android:layout_marginTop="10dp"
        android:text="Search"></Button>

    <TextView
        android:id="@+id/ans_all"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/b_Select"
        android:text="ALL:"
        android:textColor="@android:color/holo_blue_bright"
        android:textSize="30dp"></TextView>

    <TextView
        android:id="@+id/ans_Search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/ans_all"
        android:text="模糊查询:"
        android:textSize="30dp"></TextView>

</RelativeLayout>
java操作类
package com.example.test;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.test.Help.MyDbHealper;

public class Activity_Test extends AppCompatActivity {

    Button b1, b2, b3, b_select, b_search;
    EditText id, phone, like_text;
    TextView ans_All, ans_Search;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);

        findView();
        b1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String Id = id.getText().toString();
                        String Phone = phone.getText().toString();
                        Insert(Id, Phone);
                    }
                }
        );
        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String Id = id.getText().toString();
                        delete(Id);
                    }
                }
        );
        b3.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String Id = id.getText().toString();
                        String Phone = phone.getText().toString();
                        update(Id, Phone);
                    }
                }
        );

        b_select.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        select_All();
                    }
                }
        );
        b_search.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Search_name(like_text.getText().toString());
                    }
                }
        );
    }

    private void findView() {
        b1 = findViewById(R.id.b_insert);
        b2 = findViewById(R.id.b_delete);
        b3 = findViewById(R.id.b_update);
        b_search = findViewById(R.id.b_Search);
        b_select = findViewById(R.id.b_Select);
        ans_All = findViewById(R.id.ans_all);
        ans_Search = findViewById(R.id.ans_Search);
        id = findViewById(R.id.id);
        phone = findViewById(R.id.phone);
        like_text = findViewById(R.id.likeText);
    }

    //  是自己定义的方法
    private void execute(String sql, Object[] args) {
//      新建数据库帮助类
        MyDbHealper healper = new MyDbHealper(Activity_Test.this);
//      获取数据库对象
        SQLiteDatabase db = healper.getWritableDatabase();
//      执行数据库语句
        db.execSQL(sql, args);
//      关闭数据库
        db.close();
    }


    private void Insert(String Id, String Phone) {
        String sql = "insert into people (name, phone) values(?, ?)";
//        用基类来接收信息
        Object[] args = {Id, Phone};
        execute(sql, args);
        Toast.makeText(this, "Insert successfully", Toast.LENGTH_SHORT).show();
    }

    private void delete(String Id) {
        String sql = "delete from people where name = ?";
        Object[] args = {Id};
        execute(sql, args);
        Toast.makeText(this, "Delete successfully", Toast.LENGTH_SHORT).show();
    }

    private void update(String Id, String Phone) {
        String sql = "update people set phone = ? where name  = ?";
        Object[] args = {Phone, Id};
        execute(sql, args);
        Toast.makeText(this, "Update successfully", Toast.LENGTH_SHORT).show();
    }

    private void select_All() {
        MyDbHealper healper = new MyDbHealper(Activity_Test.this);
        SQLiteDatabase database = healper.getReadableDatabase();
        String sql = "select name, phone from people";
        Cursor cursor = database.rawQuery(sql, null);
        String s = "通讯录:\n";
        while (cursor.moveToNext()) {
            String namet = cursor.getString(0);
            String phonet = cursor.getString(1);
            s += "姓名:" + namet + "   \t" + "电话:" + phonet + "\n";
        }
        cursor.close();
        ans_All.setText(s);
    }

    private void Search_name(String name) {
        MyDbHealper healper = new MyDbHealper(Activity_Test.this);
        SQLiteDatabase database = healper.getReadableDatabase();
        String sql = "select name, phone from people where name like ?";
        String[] res = {"%" + name + "%"};
        Cursor cursor = database.rawQuery(sql, res);
        String s = "查询到:\n";
        while (cursor.moveToNext()) {
            String namet = cursor.getString(0);
            String phonet = cursor.getString(1);
            s += "姓名:" + namet + "   \t" + "电话:" + phonet + "\n";
        }
        cursor.close();
        ans_Search.setText(s);
    }


}
java数据库帮助类
package com.example.test.Help;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDbHealper extends SQLiteOpenHelper {
    public MyDbHealper(Context context) {
        super(context, "friend.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE  people(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(20), phone varchar(20))";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

五、网络编程

5.0 Handler

作用: 在不同线程中传输数据

Message的参数:

int what 这是用户自定义的一个整型值,用于区分消息类型。

Object obj 这是消息所携带的数据

  1. 接收数据的进程:
			Handler handler = new Handler(){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if(msg.what == 1){
                    // 获取数据
                    String s = (String) msg.obj;
                    ...对数据进行操作...
                }
            }
        };
  1. 发送数据的进程
			Message message = new Message();
			// 消息类型 自己定义
			message.what = 1;
			// 数据
			message.obj = s;
			// 发送
			handler.sendMessage(message);

5.1 Http

从网址上获取源码

        // URL地址
        URL url = new URL("http://121.36.62.78/");
		// 
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// 获取数据流
        InputStream is = conn.getInputStream();
		// 
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String s = "";
        String line;
        while ((line = reader.readLine()) != null) {
            s += line + "\r\n";
        }
        reader.close();
        is.close();
		// 现在s中的是网页的内容

样例1:读取指定界面的源代码

xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/b1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:layout_toLeftOf="@+id/b_delete"
        android:text="连接Http"></Button>

    <Button
        android:id="@+id/b2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:layout_toLeftOf="@+id/b_delete"
        android:text="Hello Word"></Button>
    <EditText
        android:id="@+id/getId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="网址"
        android:textSize="30dp"
        ></EditText>
    <TextView
        android:id="@+id/resulet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="结果:"
        android:textSize="30dp"></TextView>

</LinearLayout>
java

public class Activity_Test extends AppCompatActivity {

    Button b1, b2;
    TextView textView;
    Handler handler;
    EditText text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);
        findView();

        handler = new Handler() {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1) {
                    String s = (String) msg.obj;
                    textView.setText(s);
                }
            }
        };
        b1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
//                        用匿名内部类来定义进程
                        Runnable runnable = new Runnable() {
                            @Override
                            public void run() {
                                String s = getWeb();
                                Message message = new Message();
                                message.what = 1;
                                message.obj = s;
                                handler.sendMessage(message);
                            }
                        };
                        Thread thread = new Thread(runnable);
                        thread.start();
                    }
                }
        );
        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(Activity_Test.this, "Hello", Toast.LENGTH_SHORT).show();
                    }
                }
        );
    }

    private String getWeb() {
        String s = "";
        try {
            String id = text.getText().toString();
            System.out.println(id + "  ****************");
            URL url = new URL(id);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            InputStream is = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = reader.readLine()) != null) {
                s += line + "\r\n";
            }
            System.out.println(s);
            reader.close();
            is.close();
            Log.i("momo", s);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }


    private void findView() {
        b1 = findViewById(R.id.b1);
        b2 = findViewById(R.id.b2);
        textView = findViewById(R.id.resulet);
        text = findViewById(R.id.getId);
    }
}

5.2 登录

package com.example.test;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class Activity_Test extends AppCompatActivity {

    Button b1, b2;
    TextView ans;
    Handler handler;
    EditText name, pass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity__test);
        findView();

        handler = new Handler() {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                Toast.makeText(Activity_Test.this, "123", Toast.LENGTH_SHORT).show();
//                if (msg.what == 1) {
                Toast.makeText(Activity_Test.this, "456", Toast.LENGTH_SHORT).show();
                String s = msg.obj.toString();
                ans.setText(s);
                int status = 0;
                String back_msg = "";
                try {
                    JSONObject jsonObject = new JSONObject(s);
                    status = jsonObject.getInt("status");
                    back_msg = jsonObject.getString("msg");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                Toast.makeText(Activity_Test.this, status + " " + back_msg, Toast.LENGTH_SHORT).show();
            }
//            }
        };
        b1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        tryLogin();
                    }
                }
        );
        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Go();
                    }
                }
        );
    }

    private void tryLogin() {
        String sname = name.getText().toString();
        String spass = pass.getText().toString();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                URL url = null;
                try {
                    url = new URL("http://www.qingsongcn.com/?action=save");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("POST");
                    String s = "logonId=" + sname + "&reffers=&cmd=&logonpsw=" + spass;
                    OutputStream os = conn.getOutputStream();
                    os.write(s.getBytes());
                    InputStream is = conn.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    String res = "", line;
                    while ((line = reader.readLine()) != null) {
                        res += line + "\n";
                    }
                    reader.close();
                    is.close();
                    conn.disconnect();
                    Message message = new Message();
                    message.what = 1;
                    message.obj = res;
                    handler.sendMessage(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    private void Go() {

        String sname = name.getText().toString();
        String spass = pass.getText().toString();
        for (int i = 0; i < 1000; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    URL url = null;
                    try {
                        url = new URL("http://www.qingsongcn.com/?action=save");
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        conn.setRequestMethod("POST");
                        String s = "logonId=" + sname + "&reffers=&cmd=&logonpsw=" + spass;
                        OutputStream os = conn.getOutputStream();
                        os.write(s.getBytes());
                        InputStream is = conn.getInputStream();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                        String res = "", line;
                        while ((line = reader.readLine()) != null) {
                            res += line + "\n";
                        }
                        reader.close();
                        is.close();
                        conn.disconnect();
                        Message message = new Message();
                        message.what = 1;
                        message.obj = res;
                        handler.sendMessage(message);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }


    private void findView() {
        b1 = findViewById(R.id.b1);
        b2 = findViewById(R.id.b2);
        name = findViewById(R.id.name);
        pass = findViewById(R.id.pass);
        ans = findViewById(R.id.ans);
    }
}

5.3 小例子

六、内容提供者

内容提供者(ContentProvider)是Android系统四大组件之一,它是不同应用程序之间进行数据共享的标准API,通过ContentResolver类可以访问ContentProvider中共享的数据。

至于是哪个程序,通过Uri确定

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CfUAexET-1625377200744)(https://z3.ax1x.com/2021/05/31/2m1JW6.png)]

内容提供者(ContentProvider)中的数据存放格式和数据库

内容提供者(ContentProvider)组件的创立:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-myBG8Wga-1625377200744)(https://z3.ax1x.com/2021/05/31/2m3Nhq.png)]

创建中的2m30jU.png

URI应该就是地址,测试随便写:bzu.com

在配置文件中会有体现

内容提供者创建完成后,Android Studio会自动在AndroidManifest.xml中对内容提供者进行注册。

			<provider
            android:name=".MyContentProvider"
            android:authorities="bzu.com"
            android:enabled="true"
            android:exported="true"></provider>

6.1 读取短信

找到系统短信的ContentProvider的Uri地址
了解系统短信的数据库文件
用户交互界面的设计与实现
实体类(SmsInfo.java)的创建
界面逻辑代码的设计与实现
添加读取短信权限

首先获取权限

<uses-permission android:name="android.permission.READ_SMS"></uses-permission>

但是光这个还不行,需要在java代码中动态获取权限

java主函数:

 ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.READ_SMS}, 1);

需要一个方法:

有三个参数:请求码,请求的所有权限,应该是请求的权限对应的数
如果是符合申请的权限就是执行方法
	@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode != 1)
            return;
        for (int i = 0; i < permissions.length; i++) {
//            PackageManager.PERMISSION_GRANTED - 这个状态表示允许读取系统短信
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                readSms();
                return;
            }
        }
        Toast.makeText(this, "获取权限失败", Toast.LENGTH_SHORT).show();
    }

通过ContentResolver类接收

Uri uri = Uri.parse("content://bzu.com/"); 
    ContentResolver resolver = context.getContentResolver();
    Cursor cursor = resolver.query(Uri uri, String[] projection, String selection,
                                     String[] selectionArgs, String sortOrder);
    while (cursor.moveToNext()) {
        String address = cursor.getString(0); 
        long date = cursor.getLong(1);
        int type = cursor.getInt(2);
   }
    cursor.close();

java


import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    TextView text;
    Button b;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findView();
        b.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.READ_SMS}, 1);
                    }
                }
        );

    }

    private void readSms() {
        Uri uri = Uri.parse("content://sms/");              // 获取系统信息的uri
//        获取ContenResolver对象
        ContentResolver resolver = getContentResolver();
//        通过ContenResolver对象查询系统信息
        String[] col = {"_id", "address", "body"};
        Cursor cursor = resolver.query(uri, col, null, null, null);
        String res = "";
        while (cursor.moveToNext()) {
            res += cursor.getInt(0) + "    \t";
            res += cursor.getString(1) + "    \t";
            res += cursor.getString(2) + "\n";
        }
        cursor.close();
        text.setText(res);
    }

    private void findView() {
        text = findViewById(R.id.text);
        b = findViewById(R.id.b);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode != 1)
            return;
        for (int i = 0; i < permissions.length; i++) {
//            这个状态表示允许读取系统短信
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                readSms();
                return;
            }
        }
        Toast.makeText(this, "获取权限失败", Toast.LENGTH_SHORT).show();
    }
}

xml

<?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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/b"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Find"></Button>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="20dp"

        ></TextView>
</LinearLayout>

6.2 内容提供者 告知 观察者内容Changed

内容观察者(ContentObserver)用于观察指定Uri所代表的数据的变化,当ContentObserver观察到指定Uri代表的数据发生变化时,就会触发onChange()方法,此时在onChange()方法中使用ContentResovler可以查询到变化的数据。

要使用ContentObserver观察数据变化,就必须在ContentProvider中调用ContentResolver的notifyChange()方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iyrEGDoq-1625377200746)(https://z3.ax1x.com/2021/05/31/2mGQeg.png)]

创建内容观察者

    private class MyObserver extends ContentObserver{
        public MyObserver(Handler handler) {
            super(handler);
        }
        
// 当观察到Uri代表的数据发生变化时调用此方法,程序会回调onChange()方法,并在该方法中处理相关逻辑
        
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
          }
    }

注册内容观察者

	ContentResolver resolver = getContentResolver();
    Uri uri = Uri.parse("content://aaa.bbb.ccc");
    resolver.registerContentObserver(uri, true, new MyObserver(new Handler()));


参数:

uri 需要观察的Uri

notifyForDescendents false表示只匹配该Uri

true 表示可以同时匹配其派生的Uri

observer 创建的内容观察者对象

取消内容观察者

    @Override
protected void onDestroy() {
     super.onDestroy();
     getContentResolver().unregisterContentObserver(new MyObserver(
                                                                                                         new Handler()));
}

MyContentProvider

因为这个程序的目的不是为了实现某一个功能,只是试试

所以在insert中,通知内容–者 已经改变

    public Uri insert(Uri uri, ContentValues values) {
        // TODO: Implement this to handle requests to insert a new row.
//        throw new UnsupportedOperationException("Not yet implemented");
        getContext().getContentResolver().notifyChange(uri, null);
        return uri;
    }

java


七、广播接收者

7.1 介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aT1I5xz3-1625377200747)(https://z3.ax1x.com/2021/06/07/20Jpc9.png)]

上述图中的广播机制的实现流程具体如下:

1、广播接收者通过Binder机制在AMS(Activity Manager Service)中进行注册。

2、广播发送者通过Binder机制向AMS发送广播。

3、AMS查找符合相应条件(IntentFilter/Permission)的广播接收者

(BroadcastReceiver),将广播发送到相应的消息循环队列中。

4、执行消息循环时获取到此广播,会回调广播接收者(BroadcastReceiver)中的

onReceive()方法并在该方法中进行相关处理

Android系统中内置了很多广播,例如手机开机完成、电池电量不足时都会发送一条广播。

为了监听来自系统或者应用程序的广播事件,Android系统提供了BroadcastReceiver(广播接收者)组件。

? 20JhHx.png

创建:

选择【New】→【Other】→【Broadcast Receiver】选项来创建。

注意:

? 创建完广播接收者之后还需要对广播接收者进行注册才可以接收广播。

操作方法:

在新建的【Broadcast Receiver】类中,生成了【onReceive】方法。如果接收到信息将在此操作。

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("123", "已接受");
        throw new UnsupportedOperationException("Not yet implemented");
    }

7.2 接收广播 - 短信

		//【FirstReceiver】自己创建的广播接收者类
		// 现在要启用这个接收者
		FirstReceiver receiver = new FirstReceiver();
		// 【action】广播标识
		// 可以自己创建,下面的这个是手机短信的
		// 如果收到短信,手机短信会发送这个广播
		String action = "android.provider.Telephony.SMS_RECEIVED";
		// 
        IntentFilter filter = new IntentFilter();
        filter.addAction(action);
        registerReceiver(receiver, filter);

关闭

    // 在关闭当前activity的时候自动调用
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

代码activity

public class MainActivity extends AppCompatActivity {

    FirstReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FirstReceiver receiver = new FirstReceiver();
        String action = "android.provider.Telephony.SMS_RECEIVED";
        IntentFilter filter = new IntentFilter();
        filter.addAction(action);
        registerReceiver(receiver, filter);
    }

    // 自动调用
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
}

BroadcastReceiver

public class FirstReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("123", "已接受");
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

7.3 发送广播

Android系统提供了两种广播类型,有序广播和无序广播,开发者可根据需求为程序设置不同的广播类型。

 		String action = "bzu";
		Intent intent = new Intent();
        intent.setAction(action);
        // 注:这样是发送无序广播
		sendBroadcast(intent);
		// 有序
        sendOrderedBroadcast(intent, null);

20dDER.png

1. 无序广播

无序广播是完全异步执行,发送广播时所有监听这个广播的广播接收者都会接收到此消息,但接收的顺序不确定。

public class MainActivity extends AppCompatActivity {

    FirstReceiver receiver;
    String action = "MyAction";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        接收广播
        FirstReceiver receiver = new FirstReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(action);
        registerReceiver(receiver, filter);
    }

    // 自动调用
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    public void onClick1(View view) {
        Intent intent = new Intent();
        intent.setAction(action);
        sendBroadcast(intent);
    }
}
public class FirstReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("123", "已接受");
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
<?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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/b"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick1"
        android:text="Send"></Button>
</LinearLayout>

2. 有序广播

按照接收者的优先级接收,只有一个广播接收者能接收消息,在此广播接收者中逻辑执行完毕后,才会继续传递。

JAVA

public class MainActivity extends AppCompatActivity {

    FirstReceiver receiver;
    String action = "MyAction";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        三个广播接收者
        FirstReceiver receiver = new FirstReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(action);
        filter.setPriority(10);
        registerReceiver(receiver, filter);

        SecondReceiver receiver2 = new SecondReceiver();
        IntentFilter filter2 = new IntentFilter();
        filter2.addAction(action);
        filter.setPriority(5);
        registerReceiver(receiver2, filter2);


        ThirdReceiver receiver3 = new ThirdReceiver();
        IntentFilter filter3 = new IntentFilter();
        filter3.addAction(action);
        filter.setPriority(1);
        registerReceiver(receiver3, filter3);
    }

    // 自动调用
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    public void onClick1(View view) {
        Intent intent = new Intent();
        intent.setAction(action);
        sendBroadcast(intent);
    }
}

每一个只改输出

public class FirstReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("123", "1111");
//        throw new UnsupportedOperationException("Not yet implemented");
    }
}
public class SecondReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Log.i("123", "2222");

    }
}
public class ThirdReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Log.i("123", "3333");

//        throw new UnsupportedOperationException("Not yet implemented");
    }
}

XML同无序广播

阻断传播:

  1. 在【BroadcastReceiver】中加入:
        abortBroadcast();
  1. 发送时:
        sendOrderedBroadcast(intent, null);

这样【ThirdReceiver】就收不到广播了

7.3 插入笔记:Intent和IntentFilter

备注:摘自:https://www.jianshu.com/p/a2f826064e29

IntentFilter,顾名思义,就是Intent的过滤器。

1. Intent

Intent的意思是意图, 而就和它的意思差不多,每当我们使用 Intent的时候, 总是去想干一些事情:

我们在很多地方都会使用Intent。对于这些请求,我们都会传入一个Intent,用来Filter并启动相应的ActivityServiceBroadcastReceiver。而在这里,我们就有两种调用方式:显示调用和隐式调用。

1.1 显式调用

就像启动Activity,我们常常就是显式的调用,那何为显式调用呢?

Intent itent = new Intent();
itent.setClass(Activity_A.this, Activity_B.class);
startActivity(itent);

哦,这就是显式调用。之说以叫做显式调用,我们为Intent清楚的指出了被启动组件的信息(这里就是Activity_B),当调用了startActivity(itent)后,我们就只会很明确的知道,这次的任务是启动Activity_B,而没有其它的过程。

1.2 隐式调用

看了显式调用,应该猜都猜得到了,隐式调用就是没有明确的指出组件信息。而是通过Filter去过滤出需要的组件。

Intent intent = new Intent();
intent.setAction(Intent.ACTION_BATTERY_LOW);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.setDataAndType(Uri.EMPTY, "video/mpeg");
startActivity(intent);

这里就是一个隐式的调用,可以看到我为Intent设置了三个属性ActionCategoryData
然后startActivity(intent)就会根据我们设置的这三个属性去筛选合适的组件来打开,也就是因为这样,所以有时候,当我们APP来分享一个东西的时候,会有很多组件(比如QQ、微信、微博…)来供我们选择,因为他们都满足Filter条件。

2. IntentFilter

IntentFilter的意思就是意图过滤器,当我们隐式的启动系统组件的时候,就会根据IntentFilter来筛选出合适的进行启动。

现在我们知道了可以在Intent启动的时候对应设置ActionCategoryDataAndType,这里设置的是为了过滤的时候对应IntentFilter匹配actioncategorydata

除开过滤广播的的IntentFilter可以在代码中创建外,其它的IntentFilter都得在AndroidManifest.xml中给设置。

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
intentFilter.addCategory(Intent.CATEGORY_APP_EMAIL);
intentFilter.addDataType("video/mpeg");
Reciver reciver = new Reciver();
registerReceiver(reciver, intentFilter);

这里就是在代码中设置IntentFilter,可以看到我们设置了三个属性。让后我们再看看在AndroidManifest.xml的设置方法:

<activity  android:name=".Activity_B"    
           android:label="@string/title_activity_activity__b"
           android:launchMode="singleInstance">  
  <intent-filter> 
    <action android:name="android.intent.action.ANSWER" />    
    <category android:name="android.intent.category.APP_EMAIL" />        
    <data  android:host="www.mathiasluo.com"   
           android:scheme="http" />  
  </intent-filter>
</activity>

我们在这里给Activity设置了一个IntentFilter,但是值得注意的是,一个组件可以有多个IntentFilter,在过滤的时候只要有一个符合要求的,就会被视为过滤通过。

那我们就看看是怎样过滤的吧,首先我们应该明白一个大的思路:当我们隐式的启动一个组件的时候,就会一个一个的去过滤对应组件的全部,(比如你是隐式的启动一个Activity,就会一个一个的在全部Activity中筛选),然后根据Intent的所设置的actioncategorydata去比较IntentFilter所设置的这三个属性,相同的话就过滤留下来了。

八、服务

8.0 介绍

  1. ? Service(服务)是Android四大组件之一,能够在后台长时间执行操作并且不提供用户界面的应用程序组件。Service可以与其他组件进行交互,一般是由Activity启动,但是并不依赖于Activity。当Activity的生命周期结束时,Service仍然会继续运行,直到自己的生命周期结束为止。
  2. ? Service通常被称为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,除此之外,Service还具有较长的时间运行特性。他的应用场景主要有两个,分别是后台运行和跨进程访问。

选择【New】–【Service】–【Service】选项

(若采用创建Java类继承Service类的方式创建服务,则需要手动在清单文件中对服务进行注册。)

				  <service
                       android:name=".MyService"  // 服务的路径

                       android:enabled="true"	  // 表示系统是否能够实例化该组件

                       android:exported="true"    // 表示该服务是否能够被其他应用程序组件调用
					></service>

8.1 服务的两种启动方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tnRtKYOf-1625377200749)(https://z3.ax1x.com/2021/06/17/2zukEF.png)]

使用不同的方法启动服务,其生命周期也是不同的

1. 通过 startService() 方法启动

当通过startService()方法启动服务时,需要自身调用stopSelf()方法或者其他组件调用stopService()方法时服务才能停止。

startService()方法启动服务,服务会长期的在后台运行,并且服务的状态与开启者的状态没有关系,即使启动服务的组件已经被销毁,服务会依旧运行。

实验代码:
MyService(Service的几个方法)
package com.zhangchongwen.test1;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {
    public MyService() {
    }

	 //     通过bindService()方法启动服务时调用
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
//        throw new UnsupportedOperationException("Not yet implemented");

        Log.i("bzu", "Service onBind");
        return null;
    }

	// 在创建Service时调用
    @Override
    public void onCreate() {
        super.onCreate();

        Log.i("bzu", "Service onCreate");

    }
	// 现在不是太清楚,是在创建之后调用的
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.i("bzu", "Service onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
	// 销毁时调用
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("bzu", "Service onDestroy");
    }
}
java
img
skb

package com.zhangchongwen.test1;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    Button b1, b2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findView();
        b1.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(MainActivity.this, MyService.class);
                        startService(intent);
                    }
                }
        );

        b2.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(MainActivity.this, MyService.class);
                        stopService(intent);
                    }
                }
        );
    }

    private void findView() {
        b1 = findViewById(R.id.b1);
        b2 = findViewById(R.id.b2);
    }
}
xml
<?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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/b1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service"></Button>

    <Button
        android:id="@+id/b2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Destroy Service"></Button>

</LinearLayout>
输出:
点击开启
06-17 21:00:38.548 2324-2324/com.zhangchongwen.test1 I/bzu: Service onCreate
06-17 21:00:38.548 2324-2324/com.zhangchongwen.test1 I/bzu: Service onStartCommand

点击暂停
06-17 21:00:42.153 2324-2324/com.zhangchongwen.test1 I/bzu: Service onDestroy

2.通过 bindService**()** 方法启动

当通过bindService()方法启动服务时,需要调用onUnbind()方法解除绑定之后服务才会被销毁


通过bindService()方法启动服务时,服务会与组件绑定。当调用onUnbind()方法时,这个服务就会被销毁。

     bindService(Intent service,ServiceConnection conn, int flags)

用于指定要启动的Service
用于监听调用者与Service之间的连接
用于指定绑定时是否自动创建Service

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-05 20:23:48  更:2021-07-05 20:24:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 13:08:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码