安卓应用开发概念冲刺(概念与代码)
前三章
- 安卓整体体系结构(四个)以及其中包含什么
- 安卓将()和()分离?
- intent和Service的用处、ContentProvider用处
- 安卓四大核心组件
- Toast代码用法
第四章 Activity
- activity和xml的对应关系
- Activity的四种状态
- Activity栈的进出顺序
- Activity的7个回调函数(7个生命周期)
- Activity生命周期图**【很重要】**
- 项目配置文件AndroidManifest.xml包含内容
- 回调函数调用顺序:【很重要】
- 正常启动程序
- 程序启动后点击返回
- 正常启动后按Home键
- 按Home键后再单击应用进入
- 正常启动后切换为横屏(Ctrl+F11)
- 锁屏后解锁
- 来电通话后挂机
- Log的5种等级
第五章 Android用户界面
- 移动用户界面设计应解决的问题(3个)
- 安卓界面框架采用的模式以及各个部分的解释
- RelativeLayout相对布局的特点、优点
- LinearLayout线性布局的特点
- FrameLayout帧布局的特点
- 事件响应方式(即onClick函数的绑定方式)(5种)
第六章 Intent
- intent对于Activity、Service、Broadcast的作用
- intent的基本概念(在什么之间进行什么)
- intent启动Activity的两种方式
- 使用intent在活动间传递数据(单向、双向)(传递普通数据、对象数据)
第七章 安卓广播机制Broadcast
- Broadcast的基本概念(在什么之间进行什么)
- Broadcast实质是什么(将什么用什么方法发送出去)
- 两种类型的广播
- BroadcastReceiver是干什么用的、怎么注册(四大组件之一)
- 消息广播标识串会在哪三个地方用到
第八章 Service
- Service的特点(生命周期?可视化界面?运行在哪里?)
- 两种Service及各自的特点(用在哪里?如何开启和结束?)
- Service生命周期(这个会考吗)
第九章1 SharedPreference
- SP(简称)用在哪里?
- SP可以实现不同程序间的数据共享(3种访问方式)
- SP完全屏蔽对文件系统的操作过程
第九章2 SQLite
- 使用ListView的两个关键点
第十章 ContentProvider
- CP(简称)提供了什么
- 通过CP访问数据有什么优点
- 使用什么才能访问CP提供的数据?
- 什么是CP数据集?什么是URL?
- CP的基本操作(如何创建CP?如何实现增删改查)
第十一章 多线程和消息处理机制
- 进程和线程的区别(谁包含谁?)
- 多线程的目的
- Handler消息处理机制种,子线程和主线程是如何通信的?
第十二章 Android网络编程
略
第十三章 Fragment
- Fragment是干啥的(嵌入在哪?是什么?能干啥?)
第十四章 侧滑菜单和Tab导航
都是代码示例
第十五章 Android传感器应用
略
代码(顺序不分先后,据说activity互传intent比广播重要)
一、发送广播以及Bundle的使用
发送方
-
发送自定义广播
EditText et1=(EditText)findViewById(R.id.editText1); EditText et2=(EditText)findViewById(R.id.editText2); RadioButton rb=(RadioButton)findViewById(checkedId); String a=et1.getText().toString(); String b=et2.getText().toString(); String op=rb.getText().toString(); Intent intent=new Intent("wust.zz.mybroadcast"); Bundle bundle=new Bundle(); bundle.putString("a",a); bundle.putString("b",b); bundle.putString("op",op); intent.putExtras(bundle); sendBroadcast(intent); Log.d("msg","广播发送成功");
-
与之配套的AndroidManifest.xml中静态注册Broadcast Filter(告诉系统这个BroadcastReceiver要接收哪种广播消息(Intent-filter))
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true" > <intent-filter> <action android:name="wust.zz.mybroadcast" /> </intent-filter> </receiver> <!-- 补充:动态注册 --> IntentFilter filter = new IntentFilter(); filter.addAction("wust.zz.mybroadcast"); BroadcastReceiver receiver = new MyReceiver(); registerReceiver( receiver , filter);
-
系统广播的注册如下:
<receiver android:name="wustzz.helloandroid.MyReceiver" android:enabled="true" android:exported="true" > <intent-filter> <action android:name="android.intent.action.ACTION_SHUTDOWN" /> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver>
-
给APP添加处理拨打电话的权限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
-
添加权限申请代码
if (ActivityCompat.checkSelfPermission( MainActivity.this, Manifest.permission.PROCESS_OUTGOING_CALLS)!= PackageManager.PERMISSION_GRANTED ){ ActivityCompat.requestPermissions( MainActivity.this,new String[] { Manifest.permission.PROCESS_OUTGOING_CALLS }, 123); return; }
接收端
-
接收端处理广播消息
public class TestReceiver extends BroadcastReceiver { … @Override public void onReceive(Context context, Intent intent) { if( intent.getAction().equals( "wust.zz.mybroadcast" ) ) { //处理该广播消息 } } }
-
系统拨号案例的接收端代码:
public class MyReceiver extends BroadcastReceiver { … public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) { String phoneNum = intent.getStringExtra( Intent.EXTRA_PHONE_NUMBER ); Toast.makeText( context, "监听到拨打电话:" +phoneNum, Toast.LENGTH_SHORT ).show(); //其他操作,如启动另一个Activiy: //Intent it = new Intent( context, ***Activity.class ); //context.startActivity(it); } } }
二、Intent的使用(Activity之间的信息传递以及启动)
启动Activity
-
使用Intent启动Activity的两种情况
// 显示启动 Intent intent = new Intent(A_Activity.this, B_Activity.class); startActivity(intent); // 隐式启动 Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse("http://www.163.com") ); startActivity(intent); // 隐式启动方式二 Intent intent = new Intent( ); intent.setAction(Intent.ACTION_VIEW); // Intent动作(系统提供) intent.setData(Uri.parse("http://www.163.com")); // Intent数据 startActivity(intent);
Activity传递信息【这里老师着重提及】
-
单项传递数据(这里传递的是普通数据,bundle还可以传递对象数据,具体请见主md)
// A端代码 Intent intent = new Intent(A_Activity.this, B_Activity.class); Bundle bundle=new Bundle(); bundle.putString("name", "wustzz"); //给Bundle添加key-value值对 intent.putExtras(bundle); //为intent设置bundle startActivity(intent); //启动B // B端代码 Intent intent= getIntent(); //获取传递过来的intent Bundle bundle=intent.getExtras(); //取出intent中的bundle String name=bundle.getString("name"); //取出key对应的value
-
双向传递数据(给出的是反向传递数据的核心框架,不包括正向传递)(建议看看主md文件中的示意图)
// A端代码 Intent intent = new Intent(A_Activity.this, B_Activity.class); //如有需要intent可以给B传递Bundle(略) startActivityForResult(intent, 100); // 自设requestCode=100 // B端代码 Intent intent=getIntent(); //取得A传过来的Intent //如有需要处理从A传过来的Bundle(略) Bundle bundle2=new Bundle(); //如需要则新建要传回的Bundle bundle2.putString("key值", "value值"); intent.putExtras(bundle2); setResult(RESULT_OK, intent); //resultCode回传一个RESULT_OK(-1)标记 finish(); //必须的,用于关闭B端,返回A端
-
A端接收返回信息的代码:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==100){ //表明是B的回传 if (resultCode==RESULT_OK) { //B回传的某个结果标记 //处理B回传的数据 Bundle b=data.getExtras(); String str=b.getString("key值"); … } if (resultCode==其他标记值) { //B中传回的其他一个标记(如果有的话) … } } }
-
-
非常建议回去看看双向传递数据示例1,这里直接给出所有的代码
为了实现A_Activity输入两个数,B_Activity求和并返回值
// A端Activity主要代码 @Override protected void onCreate(Bundle savedInstanceState) { … Button btn=(Button)findViewById(R.id.button1); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EditText et1=(EditText)findViewById(R.id.editText1); EditText et2=(EditText)findViewById(R.id.editText2); String a=et1.getText().toString(); String b=et2.getText().toString(); Intent intent=new Intent(A_Activity.this,B_Activity.class); Bundle bundle=new Bundle(); bundle.putString("a", a); bundle.putString("b", b); intent.putExtras(bundle); startActivityForResult(intent, 100); //关键语句 } }); } // B_Activity主要代码 @Override protected void onCreate(Bundle savedInstanceState) { … Intent intent=getIntent(); Bundle bundle=intent.getExtras(); String a=bundle.getString("a"); String b=bundle.getString("b"); int sum=Integer.parseInt(a)+Integer.parseInt(b); bundle.putInt("sum", sum); //换成int数据 intent.putExtras(bundle); setResult(RESULT_OK, intent); //关键语句 finish(); } // A_Activity主要代码2 -- 关键事件onActivityResult @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { … if(requestCode==100) if(resultCode==RESULT_OK){ Bundle bundle=data.getExtras(); int s=bundle.getInt("sum"); TextView tv=(TextView)findViewById(R.id.textView3); tv.setText("结果="+s); } }
三、简单组件的xml文件(属性)
注意,这里并没有整理诸如【在程序中控制TextView、RadioGroup选中项改变事件】这样的代码,如果想要查看请前往主md文件查看
TextView
<TextView
android:id="@+id/textView1" //组件id,@+id表示新建id资源
android:layout_width="match_parent" //组件宽度
android:layout_height="wrap_content" //组件高度
android:textColor="#ff0000" //字体颜色
android:textSize="20sp" //字体大小
android:textStyle="normal|bold|italic" //字形
android:gravity="top|center|…" //文字对齐方式
android:text="用户名:" /> //也使用引用形式:如@string/***
ImageView
<ImageView
android:id="@+id/imageView" //组件id
android:scaleType="缩放类型" //默认fitCenter:等比缩放填充控件大小,
//并居中展示; fitStart:等比缩放靠左显示
android:src="@drawable/ic_launcher" /> //要显示的图片
Button、ImageButton与ToggleButton
<Button
android:id="@+id/button"
android:text="提交" />
<ImageButton
android:id="@+id/imageButton"
android:src="@drawable/login" />
<ToggleButton
android:id="@+id/toggleButton"
android:textOff="关闭" //设置关闭时显示的文字(默认为OFF)
android:textOn="打开" /> //Switch控件用法同ToggleButton
EditText
<EditText
android:id="@+id/editText" //组件id
android:maxLength="10" //限制输入或显示的文本长度
android:singleLine="true" //单行文本(默认可多行)
android:ems="10" //设置TextView显示宽度为N个汉字宽度
android:inputType="textPassword" //设置为密码框
android:hint="提示信息" //设置提示信息(text属性设置为空才显示)
android:text="输入值">
<requestFocus /> //当前TextView获得焦点
</EditText>
<--! 补充:inputType的取值 -->
android:inputType="numberPassword" 数字密码框
android:inputType="textMultiLine" 多行文本
android:inputType="number" 数字键盘(只能输入数字)
android:inputType="phone" 拨号键盘
android:inputType="time" 时间键盘
<--! 补充:其他属性 -->
android:digits="abcd" 只能输入abcd这四种字符
RadioGroup
<RadioGroup
android:id="@+id/radioGroup" //RadioGroup的id
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" > //horizontal:水平排列,vertical:垂直排列
<RadioButton
android:id="@+id/radioButton1" //RadioButton的id
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true" //设置选中
android:text="男" /> //设置按钮显示的文字
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女" />
</RadioGroup>
CheckBox
<CheckBox
android:id="@+id/checkBox"
android:text="Android编程" />
位置属性补充(老师最后的PPT考到了唉)
android:gravity 与 android:layout_gravity 的共有属性
属性值 | 代表的含义 |
---|---|
top,bottom | 位于其容器的顶部,底部 |
left,right | 位于其容器的左侧,右侧 |
center,fill | 居中,填满其容器 |
center_vertical | 垂直方向上居中对齐 |
center_horizontal | 水平方向上居中对齐 |
fill_vertical | 垂直方向填充 |
fill_horizontal | 水平方向填充 |
clip_vertical | 垂直方向裁剪,剪切基于其纵向对齐设置,顶部对齐时,剪切底部;底部对齐时剪切顶部;除此之外剪切顶部和底部 |
clip_horizontal | 水平方向裁剪,剪切基于其横向对齐设置,左侧对齐时,剪切右侧;右侧对齐时剪切左侧;除此之外剪切左侧和右侧 |
- gravity属性是对view控件本身来说的,是用来设置控件本身的内容应该显示在该控件的什么位置。
- 例如:在TextView中android:gravity=”right”表示TextView中文本在TexView的右侧。
- layout_gravity属性是相对于包含该元素的父元素来说的,设置该元素在父元素的什么位置。
- 例如:在TextView中android:layout_gravity=”center”表示TextView位于整个界面的中间。
- 注意:
- 对于LinearLayout,如果设置 android:orientation=”vertical”,那么layout_gravity的设置只在水平方向生效;如果设置 android:orientation=”horizontal”,那么layout_gravity属性只在垂直方向生效。
margin属性和padding属性
//margin一般用来描述子控件与父控件的位置关系,即外边距。
android:layout_marginLeft=”1dp”
android:layout_marginRight=”2dp”
android:layout_marginTop=”5dp”
android:layout_marginBottom=”10dp”
android:layout_margin=”10dp” //上下左右与父控件相距10dp
//margin一般用来描述子控件与父控件的位置关系,即外边距。
android:padding_left=”1dp”
android:padding_Right=”2dp”
android:padding_Top=”5dp”
android:padding_Bottom=”10dp”
android:padding=”5dp” //控件内容上下左右均与控件边框相距5dp
四、Service相关代码
MyService.java
public class MyService extends Service {
@Override
public void onCreate() {
// 第一次调用 startService 时调用,创建Service
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 每次调用 startService 时调用
// intent 可以接收到传来的数据
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// stopService stopSelf 调用后
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
AndroidManifest.xml
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" />
MyActivity.java
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Intent intent = new Intent(MyActivity.this, MyService.class);
// 启动服务
startService(intent);
// 停止服务
stopService(intent);
}
}
五、其他代码
Toast的使用
Toast toast=Toast.makeText( 参数1, 参数2, 参数3 );
//参数1:当前的上下文环境,getApplicationContext()或用:某个Activity.this
//参数2:要显示的字符串
//参数3:显示的时间长短,Toast.LENGTH_SHORT 或 Toast.LENGTH_LONG
toast.show(); //显示toast
Button注册响应事件(5种)
//方式1:匿名接口实现
Button bt=(Button)findViewById(R.id.button1);
bt.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
// 代码
}
});
//方式2:内部类实现接口
public class MainActivity extends Activity { //外部类
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button)findViewById(R.id.button1);
bt.setOnClickListener( new mybuttonlistener() );
}
//内部类
private class mybuttonlistener implements View.OnClickListener{ //内部类实现监听接口
@Override
public void onClick(View v) {
// 事件代码
}
}
}
//方式3:绑定监听器 (也较常用)
//先定义一个监听器
View.OnClickListener buttonListener = new View.OnClickListener(){
@Override
public void onClick(View v) { switch( v.getId() ){
case R.id.button1: …
case R.id.button2: …
}
};
//然后将监听器绑定给对象
button1.setOnClickListener(buttonListener);
button2.setOnClickListener(buttonListener);
//优势: 这种方式允许多个按钮注册 到同一个事件的监听器上,实现代码重用
//方式4:activity实现接口
public class MainActivity extends Activity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
…
Button bt=(Button)findViewById(R.id.button1);
bt.setOnClickListener( this );
}
@Override
public void onClick(View v) {
switch( v.getId() ){
case R.id.button1: …
case R.id.button2: …
}
}
}
//方式5:在组件的属性中绑定事件(紧耦合不推荐)
<Button
android:id="@+id/button1"
android:text="提交"
android:onClick="bt1Click"/>
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
…
}
public void bt1Click(View view){
// 处理事件代码
}
}
Activity注册代码(AndroidManifest.xml)
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AddRelationActivity"
android:label="@string/app_name">
</activity>
<activity
android:name=".Exam2ShowInfoActivity"
android:exported="false" />
几个常见布局的xml示例(源自实验一,不一定对,只供参考)
LinearLayout
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<CheckBox
android:id="@+id/exam1_rp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/RememberPassword" />
<CheckBox
android:id="@+id/exam1_al"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="@string/AutoLogin" />
</LinearLayout>
TableLayout
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView9"
android:layout_width="46dp"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/Account"
android:textSize="16sp" />
<EditText
android:id="@+id/editTextTextPersonName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:ems="10"
android:hint="请输入您的账号"
android:inputType="textPersonName"
android:textColor="#000000"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView10"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/Password"
android:textSize="16sp" />
<EditText
android:id="@+id/editTextTextPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:ems="10"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="parent" />
</TableRow>
</TableLayout>
FrameLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<Button
android:id="@+id/lab1_bt_forgetpw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginLeft="70dp"
android:text="@string/ForgetPassword" />
<Button
android:id="@+id/lab1_bt_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="70dp"
android:text="@string/Register" />
</FrameLayout>
RelativeLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="38dp"
android:text="Loading..."
android:textAlignment="center" />
</RelativeLayout>
其他考试注意项
- 移动计算技术:主要是第0~8章,特别是activity的启动,以及传值,考试共3个大题,选择题,简答题,编程题,编程题不会写全部程序,也不会让你写所有接口,所以考试的时候会让大家做程序的填充,填充一段程序,而不是写所有的程序,listener intent bundle,只要把里面的逻辑写好就行,接下来的课很多,只带着大家浏览,是进阶课,大部分不会考察,不会出编程题,会出简答题
- 9.1SharedPerformance后半部分考的少,SQLite稍微重要一些
考试时会让大家补充xml文件 - activity交互和启动,生命周期相关问题
- 请求权限(权限声明)
- 大题是activity和xml相关的
其他考试注意事项
- activity 生命周期流程图要能画出来,效果类似ppt 简述生命周期
如何设置view的宽度。具体说明哪个属性
编程题 填空 根据题目描述把各种属性补充上 尽量写出意思 小细节错误 只要能看出你的意图都会给分(多抄抄实验的xml文件)给出的实例的流程一定要会 - activity比广播更重要
- 选择题 简答题 编程题
- 四大组件:activity service broadcastreciver contentprovider 是什么?简述功能? 重点前三个,后一个作进阶内容
- TextView id/宽/高/颜色/字体大小/字体/位置/padding/margin
- EditText 和TextView的区别: password hint… EditText需要知道的还有同TextView上面的
- 六种界面布局
- Activity生命周期 意义 分别是? Activity栈:后进先出 某一事件只允许一个处于栈顶(活动状态) 生命时候被销毁? 生命周期事件回调函数
- 广播注册 注册权限 静态/动态 权限检查和申请时需要会的
- 不考Spinner listView这种复杂的 考简单的
- service 两种启动方式分别是?区别? 生命周期 和activity生命周期的区别
- toast intent启动另一个activity相关内容
- 组件属性都有哪些?
- 双向/单向启动 intent activity 显式启动 隐式启动
- A卷编程题推测为:intent 调用activity
- 问答题还得看给的ppt 简答题刷题库