GeekBand第四周开发

本文主要介绍了Android开发中的BroadcastReceiver、Service和Widget的使用。BroadcastReceiver用于全局通信,降低耦合度;Service是后台长时间运行的组件;Widget则提供了在桌面直接操作应用的功能。文中详细讲解了它们的原理、应用场景及使用方法。
摘要由CSDN通过智能技术生成

这一周的主要内容是BroadcastReceiver , Service , Webview,Widget. 内容还是比较丰富的,想要扎实掌握,需要更多的练习。
一、BroadcastReceiver
A. 是什么
—-public abstract class
BroadcastReceiver
—- extends Object
Known Direct Subclasses
—-AppWidgetProvider
抽象类,继承Object,其中一个子类就是下边要学的AppWidget.
广播机制,本质上它就是一种组件间的通信方式.
B.为什么要用
全局通信 ,降低耦合度。 不用再持有对方的引用,就可以用broadcastReciever中的intent实现数据交流。 一个地方发送,希望很多地方接收。广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。
C.怎么用
接收系统广播,自定义广播,静态注册,动态注册
===让程序接收一条开机广播===
1.新建一个类,继承BroadcastReceiver ,重写onReceive方法。该方法内是你收到广播之后进行的操作。

public class BootCompleteReceiver  extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"开机",Toast.LENGTH_SHORT).show();
    }
}

2.在AndroidManifest.xml文件中静态注册,使用这个类名

<!--接收开机广播的权限-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!--接收系统启动后发出的一条值为android.intent.action.BOOT_COMPLETED的广播,所以在此加入相应的action-->
<receiver android:name=".BootCompleteReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

===动态注册广播接收器—–动态注册,接收网络变化广播===
1.新建内部类,继承BroadcastReceiver
2.注册,新建NetworkChangeReceiver对象,新建IntentFilter对象,给IntentFilter添加行为,注册
3.注销 , 动态注册,一定要注销。unRegisterReceiver

public class MainActivity extends AppCompatActivity {

private NetworkChangeReceiver mNetworkChangeReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//        动态注册广播接收器,需要IntentFilter,需要Action,需要regist,和静态注册的节点相对应
IntentFilter intentFilter=new IntentFilter();
//        这是接收系统广播,值为android.net.conn.CONNECTIVITY_CHANGE的action
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
mNetworkChangeReceiver = new NetworkChangeReceiver();
//        注册,参数1,自定义的广播接收器,参数2,过滤器
registerReceiver(mNetworkChangeReceiver,intentFilter);
}

@Override
protected void onDestroy() {
super.onDestroy();
//      动态注册,一定要注销。
unregisterReceiver(mNetworkChangeReceiver);
}
//      定义一个内部类,继承BroadcastReceiver,并重写onReceive方法
//      每当网络状态发送变化时,onReceive方法就会执行
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"网络变化",Toast.LENGTH_SHORT).show()
        }
    }
}

需要权限

<!--接收网络状态权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

总结:
动态注册广播接收器,可以实现灵活的注册与注销,在灵活性方面有很大的优势。但是必须在程序启动之后才能接收到广播,因为他是写在onCreate()方法中。静态注册,可以实现在程序未启动的情况下就能接收到广播。
BroadcastReceiver是一个抽象类,唯一必须重写的抽象方法 onReceive(),在这个方法内不要进行耗时操作,超过10s会被杀死。广播接收器更多的是使用内部类的方式

Service
A. 是什么
public abstract class
Service

java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.app.Service
Service是一个抽象类,父类是ContextWrapper,Context。是一个应用组件,长时间在后台操作,没有用户界面。
B. 为什么要用
Service独特性,他不需要界面,一直在后台运行,即使退出程序。另外就是Service优先级高,系统轻易不会杀死服务。
因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它。
C. 怎么用
两种使用方式,
第一种:
startService() 执行顺序,onCreate(),onStartCommand()
stopServiece 执行顺序,onDestroy()
第二种:
bindService ,主要是为了,与Serviece进行数据交流
这里写图片描述
详细写下使用bindService()与service进行数据交流执行步骤:
注册:

   <service android:name=".TestService">
   </service>

1.在activity中适当位置,调用bindService方法

bindService(new Intent(MainActivity.this,TestService.class),mServiceConnection,BIND_AUTO_CREATE);

2.该方法的第二个参数,就需要,新建一个ServiceConnection

private ServiceConnection mServiceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
        TestService.LocalBinder localBinder= (TestService.LocalBinder) service;
mTestService = localBinder.getservice();

}

@Override
public void onServiceDisconnected(ComponentName name) {

    }
};

3.Service.class同样,上边新建一个实例化对象ServiceConnection,它的onServiceConnection的第二个参数会传进一个IBinder
这个IBinder实际上是Service类中onBind()方法中返回的IBinder. 并从这个IBinder中得到Service

public IBinder onBind(Intent intent) {
    Log.i(TAG,"onBind");
    return mIBinder;
}

4.那刚开始onBind方法,是return null;的,所以新建全局变量IBinder,来返回。在Service新建一个内部类。

public class LocalBinder extends Binder{
    TestService getservice(){
return TestService.this;
}
}

5.新建IBinder,并在onBind()方法中返回

private IBinder mIBinder=new LocalBinder();

6.在Service中设立得到数据的方法。

public int getMusicProgress(){
return 18;
}

7.当activity有了,Service对象后,可以通过service中的方法,进行数据交流

if(mTestService!=null){
int progress=mTestService.getMusicProgress();
}

-8. bindService()方法停止服务,必须解绑,调用unbindService()方法

unbindService(mServiceConnection);

实际上就是activity与Service要进行数据交流。 那两个类之间,最初实际是IBinder是桥梁和管道。所以,通过IBinder得到Service.然后利用其方法开始交流.

Widget
不了解,使用起来真是不灵。
A.是什么
—public class
AppWidgetProvider
—extends BroadcastReceiver
做Widget,需要继承AppWidgetProvider类,它是BroadcastReceiver的子类。
B.为什么用
很独特,可以放在主屏幕,直接操作应用,不用点击进入应用内就可以使用。还可以放在锁屏界面,很酷炫。
C.怎么用
1.写一个类, 继承AppWidgetProvider ,实现onReceive方法

public class MusicWidget extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);

}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);

}
}

2.androidmanifest 注册

<!--桌面小部件  action 检测到widget的更新  android:resourc指定布局-->
<receiver android:name=".TestWdiget">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
android:resource="@layout/layout_setting"/>
</receiver>

3。 appwidget 的设置布局 R.layout.setting

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="320dp"
android:minHeight="140dp"
android:previewImage="@drawable/icon"
android:initialLayout="@layout/layout_widget"
android:updatePeriodMillis="20000"
android:widgetCategory="home_screen">

</appwidget-provider>

4。 widget 的具体布局 R.layout.layout_widget. 可以自行设置和普通布局一样。
5.实现 widget点击功能。

public class MusicWidget extends AppWidgetProvider {

public static final String WIDGET_BUTTON_ACTION = "widget_button_action";
//      接收
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
//        接收
if(intent!=null&& TextUtils.equals(intent.getAction(),WIDGET_BUTTON_ACTION)){
//          1.   远程视图 , 参数1,包名。。参数2, 布局文件
RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.layout_widget);
//           2.接收数据   进行处理
remoteViews.setTextViewText(R.id.widget_music_name,"1");
remoteViews.setImageViewResource(R.id.widget_start,R.drawable.pause);
//          3.更新。  发送和接收都需要更新
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
//          组件的名字
ComponentName componentName=new ComponentName(context,MusicWidget.class);
appWidgetManager.updateAppWidget(componentName,remoteViews);
}

    }
//    发送
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
//     1.   远程视图 , 参数1,包名。。参数2, 布局文件
RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.layout_widget);
//      2.发送数据
Intent intent=new Intent();
//        发给他本身
intent.setClass(context,MusicWidget.class);
intent.setAction(WIDGET_BUTTON_ACTION);
//        参数1,context  参数2,requestCode   参数3,intent  参数4,flag
PendingIntent pendingIntent=PendingIntent.getBroadcast(context,0,intent,0);
//       .设置按钮的点击事件
remoteViews.setOnClickPendingIntent(R.id.widget_start,pendingIntent);

//      3. 更新所有id的事件
//      更新。  发送和接收都需要更新
appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
}
}

一些常用方法:
onDeleted():当该类型的AppWidget每次被删除时,调用此方法
onDisabled(): 当该类型的窗口小部件(AppWidget)全被删除时,调用此方法
onEnabled(): 当第一次创建该类型的AppWidget时,调用此方法
onReceive(): 广播接受者方法,用来接受广播消息
onUpdate(): 每次创建该类型的AppWidget都会调用此方法 , 通常来说我们需要在该方法里为该AppWidget指定RemoteViews对象。

欢迎留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值