简述android编程时布局文件的作用,安卓期末考点整理

前言

临近考试,根据老师发的考试说明和例题整理出如下的复习资料

安卓的平台架构

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

安卓的基本架构

由下至上分别是:

linux内核

Android运行时

应用程序框架

应用程序

下面简述每层的作用:

linux内核

Android 平台的基础是 Linux 内核。例如,Android Runtime (ART) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。

使用 Linux 内核可让 Android 利用主要安全功能,并且允许设备制造商为著名的内核开发硬件驱动程序。

Android运行时

Android 包括了一个核心库,该核心库提供了JAVA编程语言核心库的大多数功能。

程序库

Android包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过Android应用程序框架为开发者提供服务。

应用程序框架

Android系统提供给应用开发者的本身就是一个框架,所有的应用开发都必须遵守这个框架的原则。

应用程序

所有的应用程序都是使用JAVA语言编写的,每一个应用程序由一个或者多个活动组成,活动必须以Activity类为超类,活动类似于操作系统上的进程,但是活动比操作系统的进程要更为灵活,与进程类似的是,活动在多种状态之间进行切换。

安卓的四大组件

活动----Activity

他是一种可以包含用户界面的组件,主要用于和用户进行交互

服务----Service

Service是在一段不定的时间运行在后台,不和用户交互应用组件。

广播----Broadcast Receiver

内容提供者----Content Provider

用于在不同的应用程序之间实现数据共享的功能。提供了一套完整的机制,允许一个程序访问俩一个程序中的数据,同时还能保证被访问数据的安全性

安卓清单文件的作用

它为应用指定Java包。此包名称唯一标识应用

它描述了应用的不同组件。它指定了实现这些组件并公布它们的功能。这些声明帮助Android系统识别和组件及它们可以启动的条件。

它指定应用访问API的受保护部分和其他应用交换所需的权限。

它指定应用可在其上运行的API的最低级别

它指定链接应用所必须依据的库

常用的布局和控件以及其使用方法

四种最基本的布局

总共有四种最基本的布局,分别是:

线性布局(LinearLayout)

相对布局(RelativeLayout)

帧布局(FrameLayout)

百分比布局

因为考试说明里面只有两种,所以接下来只介绍两种

LinearLayout(线性布局)

指定各个节点的排列方向

android:orientation="horizontal"

设置右对齐

android:layout_gravity="right"

当竖直布局时,只能左右对齐和水平居中,顶部底部对齐竖直居中无效

当水平布局时,只能顶部底部对齐和竖直居中

使用match_parent时注意不要把其他组件顶出去

线性布局非常重要的一个属性:权重

android:layout_weight="1"

权重设置的是按比例分配剩余的空间

RelativeLayout

组件默认左对齐、顶部对齐

设置组件在指定组件的右边

android:layout_toRightOf="@id/tv1"

设置在指定组件的下边

android:layout_below="@id/tv1"

设置右对齐父元素

android:layout_alignParentRight="true"

设置与指定组件右对齐

android:layout_alignRight="@id/tv1"

常用的控件

TextView、EditText、Button、ImageButton、ToggleButton、RadioButton、RadioGroup、Checkbox、Spinner、ListView、ImageView、WebView、ScrollView

重要的属性有:

android:id:指明控件id

android:layout_width::指明控件的宽度

android:layout_height:指明控件的高度

创建一个活动(Activity)的步骤

创建活动,编写自己的Acivity类,继承Activity类

将UI与活动关联。调用setContentView方法

在清单文件中注册活动

活动(Activity)的生命周期

活动的状态

运行状态

当一个活动处于返回栈的栈顶,也就是在屏幕的前台显示时,称为运行状态

暂停状态

如果一个Activity失去焦点(不在栈顶),但是依然可见(一个新的非全屏的Activity,例如一个对话框形式的活动,或者一个透明的Activity 被放置在栈顶),叫做暂停状态(Paused)

停止状态

如果一个Activity被另外的Activity完全覆盖掉(不在栈顶且不可见),叫做停止状态(Stopped)

销毁状态(了解)

当一个活动从返回栈移除之后就变成的销毁状态

活动的7个生命周期的方法

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

7个生命周期的方法

活动的生命周期的图

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

活动的生命周期

Intent的使用

显式Intent

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);

startActivity(intent);

上述代码的作用是打开活动SecondActivity

隐式Intent

相比隐式Intent,隐式Intent并不明确指出想要启动哪一个活动,而是指定了一系列抽象的action和category等信息,然后交由系统去分析这个Intent,并找到合适的活动去启动

使用隐式Intent

首先打开AndroidManifest.xml,添加代码:

指定好当前活动可以相应的action和category

回到MainActivity.java中

Intent intent=new Intent("com.lyy.intent.ACTION_START");

startActivity(intent);

将Intent传入我们自定义的action字符串即可

Intent的系统action

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Android系统广播action

利用Intent传值的两种方式

利用Intent直接传值

MainActivity.java —— 负责传递数据

Intent intent1=new Intent(MainActivity.this,Main2Activity.class);

intent1.putExtra("extra","hello");

startActivity(intent1);

Main2Activity —— 负责接收数据

Intent intent = getIntent();

String data = intent.getStringExtra("extra");

Log.d(TAG, "onCreate: " + data);

利用Bundle和Intent传值

MainActivity.java —— 负责传递数据

Intent intent2 = new Intent(MainActivity.this, Main2Activity.class);

Bundle bundle = new Bundle();

bundle.putString("name", "lyy");

bundle.putInt("age", 18);

bundle.putString("address", "China");

intent2.putExtras(bundle);

startActivity(intent2);

Main2Activity —— 负责接收数据

Intent intent = getIntent();

Bundle bundle = intent.getExtras();

String nameString = bundle.getString("name");

int age = bundle.getInt("age");

String addressString = bundle.getString("address");

原生方法操作SQLite数据库

创建一个类用于继承SQLiteOpenHelper类,并重写两个方法onCreate()和onUpgrade()方法用于创建和升级数据库,代码示例如下:

public class MyDatabaseHelper extends SQLiteOpenHelper {

public static final String CREATE_BOOK = "create table Book(" +

"id integer primary key autoincrement," +

"author text," +

"price real," +

"pages integer," +

"name text)";

public static final String CREATE_CATEGORY = "create table Category(" +

"id integer primary key autoincrement," +

"category_name text," +

"category_code integer)";

private Context mContext;

public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {

super(context, name, factory, version);

mContext = context;

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(CREATE_BOOK);

db.execSQL(CREATE_CATEGORY);

Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();

}

@Override

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

db.execSQL("drop table if exists Book");

db.execSQL("drop table if exists Category");

onCreate(db);

}

}

对数据库的数据进行增删改查(CRUD)操作

添加数据

先实例化之前创建的DatabaseHelper对象,并调用其getWritableDatabase()方法,设置该数据库可写

SQLiteDatabase db = databaseHelper.getWritableDatabase();

随后创建ContentValues对象,用来添加数据

ContentValues values = new ContentValues();

//开始组装第一组数据

values.put("name", "The Da Vinci Code");

values.put("author", "Dan Brown");

values.put("pages", 454);

values.put("price", 16.96);

最后执行db数据库的insert()方法

db.insert("Book", null, values);//插入第一条数据

更新数据

创建ContentValues对象,并组装要更新的数据

ContentValues values1 = new ContentValues();

values1.put("price", 10.99);

调用update()方法

db.update("Book", values1, "name = ?", new String[]{"The Da Vinci Code"});

第一个参数指定表名,第二个指定要更新的数据,第三个指定要更新的行,如果没有,则默认更新所有行。

删除数据

直接调用delete方法即可

db.delete("Book", "pages > ?", new String[]{"500"});

查询数据(最复杂)

通过调用db的query()方法,获得一个cursor对象

//查询Book表中的所有数据

Cursor cursor = db.query("Book", null, null, null, null, null, null);

在这里需要传入7个参数,作用分别如下:

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

query的7个参数及其作用

然后在对cursor对象进行遍历,获得查询到的值

while (cursor.moveToFirst()) {

String name = cursor.getString(cursor.getColumnIndex("name"));

String author = cursor.getString(cursor.getColumnIndex("author"));

int pages = cursor.getInt(cursor.getColumnIndex("pages"));

}

最后,一定记得要回收cursor对象

cursor.close();

文件存储

写文件

public void save() {

String data = "Data to save";

try {

FileOutputStream fos = openFileOutput("data", Context.MODE_PRIVATE);

fos.write(data.getBytes());

fos.close();

} catch (Exception e) {

e.printStackTrace();

}

}

读文件

public void load() {

String fileName = "abc.txt";

try {

FileInputStream fis = openFileInput(fileName);

byte[] reader = new byte[fis.available()];

if (fis.read(reader) != -1) {

String data = new String(reader);

System.out.println(data);

}

fis.close();

} catch (Exception e) {

e.printStackTrace();

}

}

共享首选项(SharedPreferences)

利用键值对的方式来存储数据,文件都是存放在/data/data//shared_prefs/目录下的,主要提供了三种方式用于得到SharedPreferences对象

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

三种方式获得SharePreferences对象

内容提供器

主要用于在不同的应用程序之间实现数据的共享功能。目前是Android实现跨程序共享数据的标准方式。一般有两种:

1.使用现有的内容提供其来读取和操作相应程序中的数据

创建自己的内容提供器给我们的程序的数据提供外部访问接口

使用本机内容提供者

Android平台提供了一些本机内容提供者有:浏览器、联系人、通话记录、媒体存储、设置。

联系人内容提供者的URI各部分:

content://contacts/people/20

content:// 指定数据受内容提供者控制。它是标准前缀

contacts:指原生Contacts内容提供者

people指contacts列表可用记录

20指Contacts列表中的第二十条记录。它是指定记录的ID

使用getContentResolver()方法获取ContentResolver对象,通过该对象的以下方法访问内容提供者

public final Uri insert(Uri url, ContentValues values)

public final int delete(Uri url, String where, String[] selectionArgs)

public final int update(Uri uri, ContentValues values, String where,String[] selectionArgs)

public final Cursor query(Uri uri, String[] projection,String selection, String[] selectionArgs, String sortOrder)

使用自定义内容提供器

创建内容提供器

新建一个类去继承ContentProvider,并重写其6个方法,代码如下:

public class MyProvider extends ContentProvider {

@Override

public boolean onCreate() {

return false;

}

@Nullable

@Override

public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {

return null;

}

@Nullable

@Override

public String getType(@NonNull Uri uri) {

return null;

}

@Nullable

@Override

public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {

return null;

}

@Override

public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {

return 0;

}

@Override

public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {

return 0;

}

}

onCreate()

初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,

返回 true 表示内容提供器初始化成功,返回 false 则表示失败。注意,只有当存在

ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。

query()

从内容提供器中查询数据。使用 uri 参数来确定查询哪张表,projection 参数用于确

定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于

对结果进行排序,查询的结果存放在 Cursor 对象中返回。

insert()

向内容提供器中添加一条数据。使用 uri 参数来确定要添加到的表,待添加的数据

保存在 values 参数中。添加完成后,返回一个用于表示这条新记录的 URI。

update()

更新内容提供器中已有的数据。使用 uri 参数来确定更新哪一张表中的数据,新数

据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行,受影响的

行数将作为返回值返回。

delete()

从内容提供器中删除数据。使用 uri 参数来确定删除哪一张表中的数据,selection

和 selectionArgs 参数用于约束删除哪些行,被删除的行数将作为返回值返回。

getType()

根据传入的内容 URI 来返回相应的 MIME 类型。

指定内容提供者的URI

public class MyProvider extends ContentProvider {

public static final int TABLE1_DIR = 0;

public static final int TABLE1_ITEM = 1;

public static final int TABLE2_DIR = 2;

public static final int TABLE2_ITEM = 3;

private static UriMatcher uriMatcher;

static {

uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);

uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM);

uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM);

uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM);

}

..........

}

实现查询方法

public class MyProvider extends ContentProvider {

..........

@Nullable

@Override

public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {

switch (uriMatcher.match(uri)) {

case TABLE1_DIR:

// 查询table1表中的所有数据

break;

case TABLE1_ITEM:

// 查询table1表中的单条数据

break;

case TABLE2_DIR:

// 查询table2表中的所有数据

break;

case TABLE2_ITEM:

// 查询table2表中的单条数据

break;

default:

break;

}

return null;

}

....

}

处理对MINE类型数据的请求

public class MyProvider extends ContentProvider {

...........

@Nullable

@Override

public String getType(Uri uri) {

switch (uriMatcher.match(uri)) {

case TABLE1_DIR:

return "vnd.android.cursor.dir/vnd.com.example.app.provider. table1 ";

case TABLE1_ITEM:

return "vnd.android.cursor.item/vnd.com.example.app.provider. table1 ";

case TABLE2_DIR:

return "vnd.android.cursor.dir/vnd.com.example.app.provider. table2 ";

case TABLE2_ITEM:

return "vnd.android.cursor.item/vnd.com.example.app.provider. table2 ";

default:

break;

}

return null;

}

................

}

注册自定义内容提供器

android:name="com.example.databasetest.DatabaseProvider"

android:authorities="com.example.databasetest.provider" >

广播接收者(BroadcastReceiver)

广播分为两种:普通广播和有序广播

普通广播

完全异步执行的广播,在广播发出后,所有的广播接收器几乎在同一时刻都会受到这条广播,没有先后顺序之分,无法被截断,效率较高

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

普通广播图示

有序广播

同步执行的广播,在广播发出后,同一时刻只会有一个广播接收器可以收到消息,且只有当该广播接收器中的逻辑执行完毕后,这条广播才会继续传递下去,有先后顺序之分,可以被截断。

8e6bb32cfb51?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

有序广播图示

注册广播接收器的方式有两种:

动态注册

在代码中注册,新建一个类,并让其继承BroadcastReceiver类,同时重新其父类中的onReceive()方法即可,这样当有广播到来的时候,onReceive()方法便会得到执行,同时需要主活动中进行广播的注册,因为全程是在代码中运行,灵活性强,便被成为动态注册,示例如下:

private class NetWorkChangeReceiverextends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// do something......

}

}

在onCreate()方法中执行:

intentFilter = new IntentFilter();

intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");

netWorkChangeReceiver = new NetWorkChangeReceiver();

registerReceiver(netWorkChangeReceiver, intentFilter);

在onDestory()方法中执行:

unregisterReceiver(netWorkChangeReceiver);//注销广播

静态注册

和动态注册相同的是,静态注册也需要创建一个类去继承BroadcastReceiver类并实现其中的onReceive()方法,但是注册的过程被放到了AndroidManifest.xml文件中了,示例如下:

MyBroadcastReceiver.java

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();

}

}

AndroidManifest.xml

android:name=".MyBroadcastReceiver"

android:enabled="true"

adroid:exported="true">

动态注册和静态注册的区别:

动态注册不是常驻型广播,也就是说广播跟随程序的生命周期。

静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行

服务

创建一个服务

新建一个类MyService集成Service,并重写其onBind()方法即可

public class MyService extends Service {

public MyService() {

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

}

当然,最为四大组件之一的Service,服务在创建的时候需要在AndroidManifest.xml文件中进行注册才能生效

android:name=".MyService"

android:enabled="true"

android:exported="true">

启动一个服务

调用startService()方法即可启动服务,传入一个intent参数即可

Intent intent = new Intent(MainActivity.this, MyService.class);

startService(intent);

关闭一个服务

调用stopService()方法即可

Intent intent = new Intent(MainActivity.this, MyService.class);

stopService(intent);

绑定一个服务

定义一个内部类,该内部类实现接口”ServiceConnection”,同时实现接口里的两个方法:”onServiceConnection”(在这个方法方法体里得到Binder对象,由该对象就能得到服务实例)、”onServiceDisConnection”(当服务被意外断开,系统将会回调这个方法)。

分别创建服务类变量、内部类变量(内部类变量需要实例化),在”onServiceConnection”方法里面用得到的服务实例将服务类变量实例化

在需要绑定服务的地方,调用bindService()方法,将内部类变量传入。

public class MainActivity extends Activity implements View.OnClickListener {

//第二步:创建内部类变量以及服务类的变量

//同时实例化内部类变量

private MService mService = null;

private MServiceConnection mServiceConnection =

new MServiceConnection();

//窗体的初始化方法

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

findViewById(R.id.bt_bind_the_service)

.setOnClickListener(this);

}

//点击事件响应函数

@Override

public void onClick(View v) {

switch (v.getId()){

case R.id.bt_bind_the_service:

Intent intent =

new Intent(MainActivity.this, MService.class);

//第三步:绑定服务那个时候将接口的实例传入

bindService(intent, mServiceConnection,

Context.BIND_AUTO_CREATE);

break;

}

}

//第一步:定义一个内部类去实现接口”ServiceConnection”

class MServiceConnection implements ServiceConnection{

//这个方法里面那个service

//就是服务类里面的onBind()方法所返回的IBinder变量了

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

//还是第二步:将服务类的变量实例化:

//将IBinder向下转型

MService.MyBinder myBinder = (MService.MyBinder)service;

//调用公有方法就能获得服务类的实例

mService = myBinder.getService();

Log.i("test","连接服务");

}

@Override

public void onServiceDisconnected(ComponentName name) {

Log.i("test", "意外断开");

}

}

}

解绑一个服务

相对于绑定一个服务和活动来说,解除服务和活动之间的绑定就显得容易很多,只需要执行unbindService()方法,并传入一个ServiceConnection()对象即可。

unbindService(connection);

服务的生命周期

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值