Android第二讲——Intent、四大组件(Activity、BroadcastReceiver、ContentProvider、Service(IntentService))

来源:互联网 发布:md5加密java代码解密 编辑:程序博客网 时间:2024/06/01 09:14

目录

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;        }    }//第二个Activitypublic 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 的结合,创建一个闹钟(若手机关机是不能使用)

  1. 声明并初始化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>![这里写图片描述](http://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;

运行结果如图:这里写图片描述

0 0
原创粉丝点击