Android基础教程——从入门到精通(上)

Posted OYMN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android基础教程——从入门到精通(上)相关的知识,希望对你有一定的参考价值。

文章目录

一、开发环境搭建

  1. 安装android studio
  2. 安装 sdk(当前使用最新版33)

  1. 手动下载gradle

    (更新:弄完之后有时候没用,可以再试试挂梯子,换网络之类的)

    如果第一次启动AndroidStudio没有报错则无需设置,这里是因为我启动完之后下载gradle报错:

    could not install gradle distribution from 'https://services.gradle.org/dist
    

    可能是网络问题连接不到,所以手动下载。

    点击上面提示的链接下载压缩包,然后解压到C:\\Users\\OYMN\\.gradle\\wrapper\\dists\\gradle-7.2-bin\\2dnblmf4td7x66yl1d74lt32g

  2. 安装模拟器

    使用androidstudio提供的模拟器,或者自行下载第三方安卓模拟器(雷电模拟器)

二、简单控件

1. 文本显示

设置文本内容有两种方式:

  • 在 XML 文件中通过属性 android:text 设置文本
  • 在 Java 代码中调用文本视图对象的 setText 方法设置文本

引用字符串资源:

  • 在XML文件中引用(@string/xxx)
  • 在Java代码中引用(R.string.xxx)

其余设置文本字体大小,颜色等都是可以通过关键词+代码提示很容易就能知道怎么写,这里就不赘述。

2. 按钮

Button继承于TextView,因此它们拥有的属性都是共通的。

除此之外,Button最重要的是点击事件。

  • 点击监听器:通过setOnClickListener方法设置。按钮被按住少于500毫秒时,会触发点击事件。

  • 长按监听器:通过setOnLongClickListener方法设置。按钮被按住超过500毫秒时,会触发长按事件。

3. 常用布局

(1)线性布局LinearLayout

特点:要不水平排列,要不竖直排列,通过orintation进行设置(horiztal为水平,vertical为竖直)

权重属性:通过layout_weight来设置,在线性布局的直接下级进行设置,表示该下级布局占据的宽高比例。

  • layout_width填0dp时,layout_weight表示水平方向的宽度比例。
  • layout_height填0dp时,layout_weight表示垂直方向的高度比例。

(3)相对布局RelativeLayout

相对布局中的视图位置由两个因素所影响:

  • 与该视图平级的其他视图
  • 上级视图(也就是它归属的RelativeLayout)

相对位置的一些取值:

(3)网格布局GridLayout

顾名思义该布局适用于表格类型的布局。

4. 图像显示

图片一般放在res/drawable目录下,设置图像显示一般有两种方法:

  • 在XML文件中,通过属性android:src设置图片资源,属性值格式形如 @drawable/不含扩展名的图片名称。
  • 在Java代码中,调用setImageResource方法设置图片资源,方法参数格式形如 R.drawable.不含扩展名的图片名称。

(1)图像的缩放问题:

ImageView本身默认图片居中显示,若要改变图片的显示方式,可通过scaleType属性设定,该属性的取值说明如下:

(2)图像按钮ImageButton:

ImageButton是显示图片的图像按钮,但它继承自ImageView,而非继承Button。

ImageButton和Button之间的区别有:

  • Button既可显示文本也可显示图片,ImageButton只能显示图片不能显示文本。
  • ImageButton上的图像可按比例缩放,而Button通过背景设置的图像会拉伸变形。
  • Button只能靠背景显示一张图片,而ImageButton可分别在前景和背景显示图片,从而实现两张图片叠加的效果。

三、Activity

Activity是安卓开发四大组件之一,非常重要。

1. Activity的启动和结束

Activity的启动这里指的是跳转,从一个页面跳转到一个新的页面,就相当于启动了一个新的页面。

示例:

bt.setOnClickListener(new View.OnClickListener()

    @Override
    public void onClick(View v) 
        Intent intent = new Intent();
        intent.setClass(MainActivity.this, MainActivity2.class);
        startActivity(intent);
    
);

结束Activity:调用 finish()

2. Activity的生命周期

onCreate:此时将页面布局加载到内存中,初始化页面。

onStart:将页面展示在屏幕。

onResume:此时页面能够和用户进行交互。

onPause:页面进入暂停状态,无法和用户进行交互。

onStop:页面不在屏幕显示。

onDestory:回收Activity占用的资源,彻底销毁该Activity。

onRestart:onStop状态可以转为onRestart状态。

onNewIntent:重用已存在的活动实例。如果一个Activity已经启动了,并且存在与当前栈,而当前栈的启动模式为SingleTask,SingleInstance,SingleTop(此时在任务栈顶端),那么再次启动该Activity的话,并不会重新进行onCreate,而是会执行onNewIntent方法。

3. Activity的启动模式

Android允许在创建Activity时设置启动模式,通过启动模式控制Activity的出入栈行为。

(1)静态设置

设置方式:打开AndroidManifest.xml文件,给activity添加属性android:launchMode。如以下表示该activity使用standard标准模式,默认也是标准模式。

<activity android:name=".JumpFirstActivity" android:launchMode="standard" />

launchMode的取值有:

(2)动态设置

通过 Intent 动态设置 Activity启动模式:

intent.setFlags();

4. Activity之间传递信息

Intent能够让Android各组件之间进行沟通。

Intent可以完成3部分工作:

  • 表明本次通信从哪里来,往哪里走,要怎么走。
  • 发送方可以携带消息给接收方,接收方可以从收到的Intent解析数据。
  • 发送方如果想要知道接收方的处理结果,接收方也可以通过Intent返回结果。

Intent的一些组成元素:

(1)显式Intent和隐式Intent

1. 显式Intent

创建方式:

  • 在Intent的构造函数中指定:

    Intent intent = new Intent(this, NextActivity.class);
    
  • 调用setClass指定:

    Intent intent = new Intent();
    intent.setClass(this, NextActivity.class);
    
  • 调用setComponent指定:

    Intent intent = new Intent();
    ComponentName component = new ComponentName(this, NextActivity.class);
    intent.setComponent(component);
    

2. 隐式Intent:

没有明确指定所要跳转的页面,而是通过一些动作字符串来让系统自动匹配。

通常是App不想向外暴露Activity的名称,只给出一些定义好的字符串。这些字符串可以自己定义,也有系统定义的。

常见的系统动作如下:

下面以调用系统拨号页面举例:

String phone = "12345";
Intent intent = new Intent();
//这里表示设置意图动作为准备拨号
intent.setAction(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + phone));
startActivity(intent);

如果想要跳转到自己定义的activity:

步骤一:在AndroidManifest.xml找到该activity,添加action和category标签,同时设置exported为true,表示允许被其他activity调用。

步骤二:调用过程和上面一样:

Intent intent = new Intent();
intent.setAction("android.intent.action.activity2");
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);

(2)向下一个Activity发送消息:

Intent重载了很多putExtra方法用于传递各种类型的信息,包括整数类型,字符串等。但是显然通过调用putExtra方法会很不好管理,因为数据都是零碎传递。所以Android引入了Bundle,其内部是一个Map,使用起来也和Map一样。

示例:

Intent intent = new Intent(this, NextActivity.class);
//通过bundle包装数据
Bundle bundle = new Bundle();
bundle.putString("stringKey", "stringValue");
intent.putExtras(bundle);
startActivity(intent);

然后下一个Activity就可以通过intent获取到所想要的数据了:

Bundle bundle = getIntent().getExtras();
String stringValue = bundle.getString("stringKey");

(3)向上一个Activity返回消息:

上一个页面跳转到下一个页面,同时携带数据:

private ActivityResultLauncher<Intent> register;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    findViewById(R.id.bt).setOnClickListener(this);

    //回调函数,返回到这个页面时所执行的程序
    register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() 
       			//回调函数
                @Override
                public void onActivityResult(ActivityResult result) 
                    if (result != null) 
                        Intent intent = result.getData();
                        if (intent != null && result.getResultCode() == Activity.RESULT_OK) 
                            //获取到返回的数据
                            Bundle bundle = intent.getExtras();
                            //...
                        
                    
                
            );


@Override
public void onClick(View v) 
    Intent intent = new Intent(this, MainActivity3.class);
    //跳转下一页面
    register.launch(intent);


下一个页面接受到数据,处理之后返回结果给上一个页面:

Bundle bundle = getIntent().getExtras();
//...页面进行处理
//返回数据给上一个页面
Bundle bundle = new Bundle();
bundle.putString("stringKey", "stringValue");
intent.putExtras(bundle);
setResult(Activity.RESULT_OK, intent);
finish();

5. Activity获取一些附加信息

(1)获取资源信息:

//获取strings.xml中的字符串资源
String text = getString(R.string.text);
//获取color.xml中的颜色资源
int black = getColor(R.color.black);

(2)获取元数据信息:

try 
    //获取包管理器
    PackageManager pm = getPackageManager();
    //获取当前的Activity信息
    ActivityInfo activityInfo = pm.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
    Bundle bundle = activityInfo.metaData;
    String text2 = bundle.getString("text2");

 catch (PackageManager.NameNotFoundException e) 
    e.printStackTrace();

四、数据存储

1. 共享参数SharedPreferences

(1)使用:

sharedPreferences是安卓的一个轻量级存储工具,采用的方式是key-value,以xml文件形式存在,文件路径为/data/data/应用包名/shared_prefs/文件名.xml。


适合场景:

  1. 简单且孤立的数据
  2. 文本数据,二进制数据则不合适
  3. 需要持久化的数据,也就是重启APP后数据仍然存在且有效。

实际开发中,sharedPreferences经常用来存储的数据有:APP的个性化配置信息,用户使用APP的行为信息等。

sharedPreferences对数据的存储和读取类似Map,提供put和set方法。

获取数据可以通过SharedPreferences对象获取:

//第一个参数表示文件名,第二个参数表示私有模式
SharedPreferences shared = getSharedPreferences("fileName", MODE_PRIVATE);
String name = shared.getString("name");

而存储数据则还需要借助Editor类:

SharedPreferences.Editor editor = shared.edit();
editor.putString("name", "oymn");
editor.putInt("age", 20);
editor.commit();

(2)应用实例:记住密码功能

  1. 声明一个共享参数对象,并在onCreate中调用getSharedPreferences方法获取共享参数的实例。
  2. 登录成功时,如果用户勾选了“记住密码”,就使用共享参数保存手机号码与密码。

所以在登录页面的onCreat方法中添加获取共享参数的代码:

// 从share_login.xml获取共享参数对象
mShared = getSharedPreferences("share_login", MODE_PRIVATE);
// 获取共享参数保存的手机号码
String phone = mShared.getString("phone", "");
// 获取共享参数保存的密码
String password = mShared.getString("password", "");
et_phone.setText(phone); // 往手机号码编辑框填写上次保存的手机号
et_password.setText(password); // 往密码编辑框填写上次保存的密码

接着在登录成功方法中添加保存功能:

// 如果勾选了“记住密码”,就把手机号码和密码都保存到共享参数中
if (isRemember) 
    SharedPreferences.Editor editor = mShared.edit(); // 获得编辑器的对象
    editor.putString("phone", et_phone.getText().toString()); // 添加名叫phone的手机号码
    editor.putString("password", et_password.getText().toString()); // 添加名叫password的密码
    editor.commit(); // 提交编辑器中的修改

2. 数据库SQLite

SQLite是安卓的一种小巧的嵌入式数据库,基本使用和思路和mysql无异。

(1)SQLiteDatabase

java代码层面借助SQLiteDatabase来对SQLite进行操作。

//创建数据库text.db
SQLiteDatabase db = openOrCreateDatabase(getFileDir() + "/test.db", Context.MODE_PRIVATE, null);

(2)SQLiteOpenHelper

由于SQLiteDatabase存在局限性,一不小心就会重复打开数据库,处理数据库的升级也不方便;因此Android提供了数据库帮助器SQLiteOpenHelper,帮助开发者合理使用SQLite。

SQLiteOpenHelper的具体使用步骤如下:

  • 步骤一,新建一个继承自SQLiteOpenHelper的数据库操作类,按提示重写onCreate和onUpgrade两个方法。其中,onCreate方法只在第一次打开数据库时执行,在此可以创建表结构;而onUpgrade方法在数据库版本升高时执行,在此可以根据新旧版本号变更表结构。
  • 步骤二,为保证数据库安全使用,需要封装几个必要方法,包括获取单例对象、打开数据库连接、关闭数据库连接,说明如下:
    • 获取单例对象:确保在App运行过程中数据库只会打开一次,避免重复打开引起错误。
    • 打开数据库连接:SQLite有锁机制,即读锁和写锁的处理;故而数据库连接也分两种,读连接可调用getReadableDatabase方法获得,写连接可调用getWritableDatabase获得。
    • 关闭数据库连接:数据库操作完毕,调用数据库实例的close方法关闭连接。
  • 步骤三, 提供对表记录增加、删除、修改、查询的操作方法。能被SQLite直接使用的数据结构是ContentValues类,它类似于映射Map,也提供了put和get方法存取键值对。
    • 区别之处在于:ContentValues的键只能是字符串,不能是其他类型。ContentValues主要用于增加记录和更新记录,对应数据库的insert和update方法。
    • 记录的查询操作用到了游标类Cursor,调用query和rawQuery方法返回的都是Cursor对象,若要获取全部的查询结果,则需根据游标的指示一条一条遍历结果集合。Cursor的常用方法可分为3类,说明如下:

(3)代码举例:

public class UserDBHelper extends SQLiteOpenHelper 

    private static final String DB_NAME = "user.db";   //数据库名称
    private static final int DB_VERSION = 1;   //数据库的版本号
    private static UserDBHelper helper = null;   //单例
    private SQLiteDatabase sdb = null;  //数据库实例
    public static final String TABLE_NAME = "user_info";   //表名

    public UserDBHelper(Context context) 
        super(context, DB_NAME, null, DB_VERSION);
    

    public UserDBHelper(Context context, int version) 
        super(context, DB_NAME, null, version);
    

    //通过单例模式获取 UserDBHelper 的唯一实例
    public static synchronized UserDBHelper getInstance(Context context, int version) 
        if (version > 0 && helper == null) 
            helper = new UserDBHelper(context, version);
         else if (helper == null) 
            helper = new UserDBHelper(context);
        

        return helper;
    

    //打开读连接
    public SQLiteDatabase openReadLink() 
        if (sdb == null || !sdb.isOpen()) 
            sdb = helper.getReadableDatabase();
        

        return sdb;
    

    //打开写连接
    public SQLiteDatabase openWriteLink() 
        if (sdb == null || !sdb.isOpen()) 
            sdb = helper.getWritableDatabase();
        

        return sdb;
    

    //关闭数据库连接
    public void closeLink() 
        if (sdb != null && sdb.isOpen()) 
            sdb.close();
            sdb = null;
        
    

    //创建数据库,执行建表语句
    @Override
    public void onCreate(SQLiteDatabase db) 
        //先删除已存在表
        String drop_sql = "drop table if exists " + TABLE_NAME + ";";
        db.execSQL(drop_sql);

        //创建表
        String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
                + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
                + "name VARCHAR NOT NULL," + "age INTEGER NOT NULL,"
                + "height INTEGER NOT NULL," + "weight FLOAT NOT NULL,"
                + "married INTEGER NOT NULL," + "update_time VARCHAR NOT NULL"
                //演示数据库升级时要先把下面这行注释
                + ",phone VARCHAR" + ",password VARCHAR"
                + ");";

        db.execSQL(create_sql);
    

    //修改表结构
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        if (newVersion > 1) 
            //Android的ALTER命令不支持一次添加多列,只能分多次添加
            String alter_sql = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN phone VARCHAR;";
            db.execSQL(alter_sql);

            alter_sql = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + "password VARCHAR;";
            db以上是关于Android基础教程——从入门到精通(上)的主要内容,如果未能解决你的问题,请参考以下文章

Daydream从入门到精通——快速入门开发基础教程二:Android端开发环境配置二

Android Studio教程从入门到精通

《Android开发从入门到精通》扶松柏.扫描版.pdf

[Android开发从入门到精通].扶松柏pdf高清版免费下载

IT教程课程分享:《MySQL DBA从入门到精通(65集)》网课资源

图解AI数学基础:从入门到精通系列教程