目录
Android的四大组件
Intent
IntentService
Android的四大组件
Android的四大组件都必须要在AndroidManifest中进行注册
Android程序的四大基本组件
Activity
BroadcastReceiver
Content Provider
Service
Activity
是用于显示界面的,与用户交互的。一个界面对应一个Activity
若一个类使用Activity需要继承Activity
Activity的生命周期:
Activity的操作
Activity的生命周期
当一个活动完全覆盖在当前活动上时,当前活动调用onPause,onStop,当返回当前活动时调用onRestart,onstart…
当一个活动未完全覆盖在当前活动上时,当前活动调用onPause,当返回当前活动时调用onResume。
了解了Android的生命周期后,就需要来学习Activity是怎么操作的了。
Activity的操作
·全屏(是否去掉信息栏)
1、初始化时加入代码 requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
2、在AndroidManifest.xml加载:
android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”
此时界面已经去掉了信息栏
·横竖屏android:scrennOrientation
landscape“横屏”
portrait “竖屏”
unspecified “默认值,由系统选择方向”
Activity的启动 Activity的启动方式,用Intent启动
1>直接启动
Intent intent = new Intent(…,…);
startActicity(intent);
button_derict.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);//第一个参数:上下文,第二个参数:将要启动的活动的类。
startActivity(intent);
}
});
2>带返回值的启动
API中有介绍
一、第一个界面调用startActivityForResult(intnet,requestCode)
二、第二个界面先调用getIntent()得到启动的Intent
三、在关闭第二个界面前先封装数据:intent.putExtra(“key”,editText.getText().toString)
四、设置resultCode :setResult(RESULT_OK,intent)
五、关闭第二个界面finish();
六、第一个界面准备接收数据重写:onActivityResult(requestCode,resultCode,Intent data)
七、判断requestCode,resultCode
八、然后从data中取出数据
//第一个Activity
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent,978);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 978:
if (resultCode == RESULT_OK){
String msg = data.getStringExtra("Kings");//获得key
textView.setText(msg);
}
break;
}
}
//第二个Activity
public class SecondActivity extends Activity {
private EditText editText;
private Button button;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
intent = getIntent();//得到启动当前Activity的Intent
button = (Button) findViewById(R.id.button_back);
editText = (EditText) findViewById(R.id.editText);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent.putExtra("Kings", editText.getText().toString());//类似于HashMap,前边是key键,后边是值。
setResult(RESULT_OK, intent);
SecondActivity.this.finish();
}
});
}
}
Intent
Android中进行通讯的工具,类似包裹内容可以使用两种去传输,一种是data,一种是extra
6大属性:
action 启动某一特定的应用,比如:打电话
public class IntentActivity extends Activity {
private Button mBtnPhone;
private Button mBtnCall;
private Button mBtnSms;
private Button mBtnWeb;
private Button mBtnHide;
private EditText mEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent);
mEditText = (EditText) findViewById(R.id.editText2);
mBtnPhone = (Button) findViewById(R.id.button_phone);
//打电话界面的点击事件
mBtnPhone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
//如果不设置Data只会调用拨号的界面,如果想拨号要设置Data
//Uri设置号码
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
});
mBtnCall = (Button) findViewById(R.id.button_call);
//直接打电话的点击事件
mBtnCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
//如果想打电话要设置Data
//Uri设置号码
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
});
mBtnSms = (Button) findViewById(R.id.button_sms);
//发送短信的点击事件
mBtnSms.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
Uri uri = Uri.parse("smsto:10086");
intent.setData(uri);
//封装后第一个参数是发送给谁"sms_body",第二个参数是发送的内容
intent.putExtra("sms_body", "话费余额");
startActivity(intent);
}
});
mBtnWeb = (Button) findViewById(R.id.button_web);
//打开网页的点击事件
mBtnWeb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});
mBtnHide = (Button) findViewById(R.id.button_hide);
//隐式启动Activity的点击事件
mBtnHide.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.lingzhuo.test");
String msg = mEditText.getText().toString();
intent.putExtra(Config.INSTANCE_TO_MAINACTIVITY, msg);
startActivity(intent);
}
});
}
}
结果如下:
data 开发拨号软件、浏览器
category
type
component
extras
隐式启动Activity
intent-filter intent过滤器
将要启动的界面在manifest中添加intent-filter 必须添加action。category是default的
<!-- 自定义的intent过滤器-->
<intent-filter>
<action android:name="com.lingzhuo.test"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
mBtnHide.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.lingzhuo.test");
String msg = mEditText.getText().toString();
intent.putExtra(Config.INSTANCE_TO_MAINACTIVITY, msg);
startActivity(intent);
}
});
结果如图:
BroadcastReceiver (广播接收器)
继承BroadcastReceiver实现onReciver方法
新建一个继承于BroadcastReceiver类的MyBroadCastReceiver
/**
* Created by Went_Gone on 2015/9/8.
*/
public class MyBroadCastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "我接收到了广播", Toast.LENGTH_SHORT).show();
}
}
在AndroidManifest.xml中注册。
<receiver android:name=".MyBroadCastReceiver">
<intent-filter>
<action android:name="com.went_gone.broadcastreceiver"/>
</intent-filter>
</receiver>
此时为静态注册,不易修改与维护。也可在代码中动态注册,可以不用在AndroidManifest注册,但在Activity退出时一定要解绑
//在代码中动态添加广播的注册,这样不需要再AndroidManifest中添加注册了,注意,Activity退出时一定要解绑
mReceiver = new MyBroadCastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.went_gone.broadcastreceiver");
registerReceiver(mReceiver,filter);//注册Receiver,参数:Receiver,IntentFilter。
@Override
protected void onDestroy() {
super.onDestroy();
//退出时,要解除广播的绑定,否则会报错
unregisterReceiver(mReceiver);
}
创建的MyBroadCastReceiver类是用来接收应用发出的广播的
Activity如何发送广播? 通过sendBroadcast();参数是一个Intent
case R.id.button_send_broad:
Intent intent = new Intent();
intent.setAction("com.went_gone.broadcastreceiver");//setAction(AndroidManifest中receiver中的action)
sendBroadcast(intent);//Activity通过sendBroadcast来发送广播。
break;
点击发送广播按钮后:
通过BrodcastReceiver与AlarmManager、PendingIntent 的结合,创建一个闹钟(若手机关机是不能使用)
- 声明并初始化AlarmManager
private AlarmManager mManager;
mManager = (AlarmManager) getSystemService(ALARM_SERVICE);//AlarmManager的初始化
2.开启闹钟
case R.id.button_alarm_start:
Intent intent1 = new Intent();
intent1.setAction("com.went_gone.broadcastreceiver");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),0x23,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
mManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+5000,4000,pendingIntent);
break;
3.关闭闹钟
case R.id.button_alarm_close:
Intent intent2 = new Intent();
intent2.setAction("com.went_gone.broadcastreceiver");
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(getApplicationContext(),0x23,intent2,PendingIntent.FLAG_UPDATE_CURRENT);
mManager.cancel(pendingIntent1);//取消PendingIntent
break;
接收系统广播 Intent中有Broadcast的Action 需要加权限
例如:接收WIFI开启关闭时。
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 在receiver中添加-->
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"></action>
![这里写图片描述](https://img-blog.csdn.net/20150909203037443)
<a id="ContentProvider">
##ContentProvider (共享数据、内容提供者)
不常用,查看联系人:
ContentResolver通过Uri查询ContentProvider
首先,在AndroidManifest中添加权限
```xml
<!-- 要加权限-->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
其次,声明并初始化ContentResolver。
private ContentResolver resolver;
resolver = getContentResolver();
然后,开始通过resolver查看联系人
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;//找到系统中电话的Uri
Cursor cursor = resolver.query(uri, new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null);//查询联系人的姓名和电话号码
cursor.moveToFirst();//移动到第一位
while (!cursor.isAfterLast()) {
StringBuffer buffer = new StringBuffer();
String[] names = cursor.getColumnNames();
for (String name : names) {
String values = cursor.getString(cursor.getColumnIndex(name));
buffer.append(values);
Log.d("Phone", "字段:" + name + " 字段值:" + values);
}
cursor.moveToNext();
}
Service (后台服务)
Service是Android系统的后台服务组件,适用于开发无界面、长时间运行的应用功能
Service的特点如下:
- 没有用户界面
- 不会轻易被Android用户终止
- 在系统资源恢复后Service也将自动恢复
- 运行状态
- 可用于进程间通讯
(所有的耗时操作放在service里,需要启动一个线程)
它的生命周期:
onCreate()—–>onStart()/onStartCommand()—–>onDestroy
在AndroidManifest中注册
启动一个服务的时候,在Activity中用Intent关联到Service上,startService()启动service。用stopService()停止service。
首先,创建一个类继承于Service 实现3个方法。
/**
* Created by Went_Gone on 2015/9/8.
*/
public class MyService extends Service{
private MainActivity mainActivity;
private int count = 0;
@Override
public void onCreate() {
super.onCreate();
Log.d("Service","onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("Service","onDestroy");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
其次,在MainActivity中,用Intent启动服务
Intent intent = new Intent(getApplicationContext(), MyService.class);
startService(intent);
会发现当活动关闭掉后,其后台还是有服务在走的,但当我们手动停止服务后,Service会调用onDestroy方法,消除Service
小练习:模拟下载:
大体流程图:
要用progressBar进度条 也可以设置Progress 默认是100,要设置它的样式。
<ProgressBar
android:id="@+id/progressbar_download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
/>
<Button
android:id="@+id/button_download_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"/>
在MyService中的onStartCommand中添加一个线程,用来模拟进度条不断增加进度。
new Thread(new Runnable() {
@Override
public void run() {
while (true){
if (count>100){
count=0;
}
count++;
Intent intent = new Intent();
intent.setAction(MainActivity.DOWN_LOAD_RECIVER);
intent.putExtra("count",count);
sendBroadcast(intent);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
在UI主线程中
case R.id.button_download_start:
Intent intent2 = new Intent(getApplicationContext(), MyService.class);
startService(intent2);
break;
运行结果如图:
IntentService
Service与IntenService的比较:
Service:IntentService
|——–|————–|
运行在主线程中:自身包含一个线程,包含一个消息队列,用于后台干一件事
要先注册
新建一个类继承于IntentService,实现onDestroy()与onHandleIntent()还有一个构造器。
在onHandleIntent中进行操作,实现上述的模拟下载思路:
在IntentService中的onHandleIntent中进行count的计数没过0.2秒+1。仅仅计数是不够的,因为你需要让UI主线程实时知道,那么就需要发送一个广播。而在Activity中负责接收广播。
/**
* Created by Went_Gone on 2015/9/9.
*/
public class MyIntentService extends IntentService{
private int count;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
public MyIntentService(){
this("");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("Service","IntentService已关闭");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d("Service","IntentService已启动");
//只有一个线程
while (true){
if (count>100){
count=0;
}
count++;
//发送广播
Intent intent1 = new Intent();
intent1.setAction(MainActivity.DOWN_LOAD_RECIVER);
intent1.putExtra("count",count);
sendBroadcast(intent1);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在Activity中 接受一个广播,初始化,并动态添加注册(记得Activity销毁时解除广播的绑定):
/**
* 接收一个广播
*/
public class MyDownLoadReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int count = intent.getIntExtra("count",3);
mProgressBar.setProgress(count);
}
}
private MyDownLoadReceiver mMyDownLoadReceiver;
public static final String DOWN_LOAD_RECIVER = "com.downloadservice";
//注册广播
mMyDownLoadReceiver = new MyDownLoadReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(DOWN_LOAD_RECIVER);
registerReceiver(mMyDownLoadReceiver,filter);
//启动服务
case R.id.button_download_start:
Intent intent2 = new Intent(getApplicationContext(), MyIntentService.class);
startService(intent2);
break;
运行结果如图: