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

目录

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

  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>
![这里写图片描述](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;

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值