前言
这个是老师的考试说明中的例题,因为Word文档实在是太丑了,所以迁移到简书上
例题
一、填空题
- 可以利用两个应用清单文件中提供的<manifest>元素的
android:sharedUserId
属性,使这两个应用在同一进程中运行。 - SQLiteOpenHelper 中有两个抽象方法,可以在这两个方法中去实现创建、升级数据库的逻辑。这两个方法分别是
onCreate()
和onUpgrade()
。 - 定义LinearLayout水平方向布局时至少设置的三个属性:
android:layout_height
、android:layout_width
和android:orientation
。 - Android安全模型的优势:
保护组件,保护API,访问控制策略,访问限制,唯一签名
- 菜单资源XML中,使用到三个元素:
<menu>、<item>和<group>
。 - Android 提供了三种类型的菜单:
选项菜单、上下文菜单、弹出菜单。
二、语句翻译
Android provides the Criteria class, which provides the application criteria to select a location provider.
翻译:
Android提供了Criteria类,它提供了选择位置提供程序的应用程序条件。
Each mobile device has an associated mobile platform. The mobile platform is responsible for determining the functions and features available on the mobile device
翻译:
每个移动设备都有一个关联的移动平台。 移动平台负责确定移动设备上可用的功能和特性
三、阅读程序题
<EditText
android:id="@+id/editText1" //(1)
android:text=""
android:gravity="top" //(2)
android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1">
</EditText>
public void playSong(final int position, final int cur_pos) {
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(MEDIA_PATH + mSongs.get(position));
mMediaPlayer.prepare(); //(3)
mMediaPlayer.seekTo(cur_pos);
mMediaPlayer.start();
mDuration=position;
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() { //(4)
public void onCompletion(MediaPlayer arg0) {
nextSong();
}
});
} catch (IOException e) {
}
}
答案:
- 指定该EditText控件id为editText1
- 设置EditText控件里的元素的位置位于该控件的顶部
- 让创建好的mMediaPlayer对象执行播放前的准备操作
- 设置mMediaPlayer播放完成的监听操作
四、简答题
- 简述Android平台的分层体系架构
android平台的四层架构:linux内核、库和android运行时、应用程序框架、应用程序
- linux内核:这一层为Android 设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi 驱动、电源管理等。
- 库和android运行时:这一层通过一些C/C++库来为Android 系统提供了主要的特性支持,同样在这一层还有Android 运行时库,它主要提供了一些核心库,能够允许开发者使用Java 语言来编写Android 应用。
- 应用框架层:这一层主要提供了构建应用程序时可能用到的各种API。
- 应用层:所有安装在手机上的应用程序都是属于这一层的。
- 简述Intent对象的组成部分
- Component name即组件名称,是要处理这个Intent对象的组件名称。
- Action是指Intent要完成的动作,是一个字符串常量。使用 setAction() 和 getAction()来设置和读取Action属性。
- Data属性是执行动作的URI和MIME类型,不同的动作有不同的数据规格。
- Category是一个字符串,提供了额外的信息,有关于能够处理这个Intent对象的组件种类,一般在隐式地启动activity时需要用到。
- Extras传递给Intent的额外数据,以Bundle的形式定义,就是一些键值对。数据可以被作为一个Bundle对象被使用,利用 putExtras() 和 getExtras() 方法。
- flags各种类型的Flag。很多是用来指定Android系统如何启动activity,还有启动了activity后如何对待它。所有这些都定义在Intent类中。
- 有哪些信息在AndroidManifest.xml文件中?
- manifest:根节点,描述了package中所有的内容。
- uses-permission:请求你的package正常运作所需赋予的安全许可。
- permission: 声明了安全许可来限制哪些程序能你package中的组件和功能。
- instrumentation:声明了用来测试此package或其他package指令组件的代码。
- application:包含package中application级别组件声明的根节点。
- activity:Activity是用来与用户交互的主要工具。
- receiver:IntentReceiver能使的application获得数据的改变或者发生的操作,即使它当前不在运行。
- service:Service是能在后台运行任意时间的组件。
- provider:ContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件。
- 简述Android中Activity布局的种类及其特点。
- 线性布局的子元素可垂直或者水平排列,但是每一列/行中,只能有一个界面元素。
- 框架布局是只存放一个元素的空白空间,且位置只能是空白空间的左上角,如果有多个子元素,后放置的子元素会遮挡先放置的子元素。
- 表格布局将屏幕划分网格,把界面元素添加到网格中,支持嵌套,也可添加其他的界面布局
- 相对布局中的界面元素的位置是通过与其他的元素的相对位置确定的,具有灵活性。
- 绝对布局的界面元素的位置是通过坐标确定的,他是不推荐使用的一种布局
- 网格布局将用户界面划分为网格,界面元素可随意摆放在这些网格中,界面元素可以占用多个网格的,使界面设计更为灵活。
- Android平台的数据存储方式有哪些?
- 使用SharedPreferences存储数据;它是Android提供的用来存储一些简单配置信息的一种机制,采用了XML格式将数据存储到设备中。只能在同一个包内使用,不能在不同的包之间使用。
- 文件存储数据;文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput()和openFileOutput()方法来读取设备上的文件。
- SQLite数据库存储数据;SQLite是Android所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。
- 使用ContentProvider存储数据;主要用于应用程序之间进行数据交换,从而能够让其他的应用保存或读取此Content Provider的各种数据类型。
- 网络存储数据;通过网络上提供给我们的存储空间来上传(存储)和下载(获取)我们存储在网络空间中的数据信息。
- 注册广播有哪几种方式,这些方式有何区别?
共有2种方式,分为静态注册和动态注册
- 静态注册是在清单文件中申明,如下:
<receive > android:name=".IncomingSMSReceiver " > <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED") <intent-filter> <receiver>
- 动态注册是在代码种进行注册,如下:
IntentFilter filter =new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); IncomingSMSReceiver receiver = new IncomgSMSReceiver(); registerReceiver(receiver.filter);
两种注册的区别:
第一种不是常驻型广播,也就是说广播跟随程序的生命周期。
第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行
- 简述Android数字签名
- 所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序
- Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
- 如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
- 数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。
- UriMatcher类是怎么使用的
在Content Provider中该类帮助匹配URI
- 首先第一步把你需要匹配Uri路径全部给注册,如下所示:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//匹配content://cn.xxt.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI(“cn.xxt.provider.personprovider”, “person”, 1);
//匹配content://cn.xxt.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI(“cn.xxt.provider.personprovider”, “person/#”, 2);//#号为通配符- 注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数。假设匹配content://cn.xxt.provider.personprovider/person路径,返回的匹配码为1,一般使用switch语句,对不同的匹配使用不同的操作,示例代码如下:
switch (sMatcher.match(uri)) {
case 1
break;
case 2
break;
default://不匹配
break;
}
- 请根据自己的理解叙述下Android中的长度单位sp和dp。
- dp(dip): device independent pixels(设备独立像素).一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。
要理解这个概念,首先要理解像素密度dpi,即单位英寸的像素点数量。假如我的手机屏幕尺寸为1.5英寸x2英寸,分辨率为240x320,那它的像素密度即为160dpi。
Android 系统定义了4种分辨率:低(120dpi)、中(160dpi)、高(240dpi)、超高(320dpi),对应的dp到px的转换系数分别是0.75、1、1.5、2,这个系数乘dp长度就是像素数。假如我的手机像素密度是240dpi,现在屏幕上有一个长度为80dp 的图片,那么显示的像素长度为80x1.5=120px。假如我另一个手机像素密度是320dpi,那么实际像素长度为160px。这样,同样的图片在不同的手机上显示的尺寸就几乎没什么区别。- sp 全称是scaled pixels。这个主要是用于项目中的字体大小。使用sp作为单位,当用户通过手机设置修改手机字体的时候,sp为单位的字体也会跟着改变。
文字用sp 单位,其他非文字用dp 单位。例如textSize="16sp"、layout_width="60dp";
- Activity事件回调函数:
- onCreate,完全生命周期开始,初始化 Activity;
- onStart,可视生命周期开始,对用户界面进行必要的更改;
- onRestoreInstanceState,恢复onSaveLnstanceState保存的用户界面信息;
- onResume,活动生命周期开始,保存界面信息;
- onSaveInstanceState,在 onResume后,保存界面信息;
- onRestart,重新进入可视生命周期前,载入界面所需要的更改信息;
- onPause,活动生命周期结束,保存持久地数据或释放占用的资源;
- onStop,可视生命周期结束,保存持久地数据或释放占用的资源;
- onDestory,完全生命周期结束,释放资源。
五、编程题
- 在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 intent1=new Intent(MainActivity.this,Main2Activity.class); intent1.putExtra("extra","hello"); startActivity(intent1);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");
- 广播接受者的编写
- 动态注册
在代码中注册,新建一个类,并让其继承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.javapublic class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show(); } }
AndroidManifest.xml
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" adroid:exported="true"> <intent-filter> <action android:name="com.lyy.broadcast.MY_BROADCAST" /> </intent-filter> </receiver>
- 内容提供者的编写
第一步,新建一个类去继承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;
}
}
第二步,指定内容提供者的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;
}
................
}
第五步,注册自定义内容提供器
<provider
android:name="com.example.mytest.myProvider"
android:authorities="com.example.mytest.provider" >
</provider>