Geekband004第四周笔记分享

Service

什么是service:

A Service is an application component representing either an
application’s desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use.

service 服务是android的一种机制,可以在后台运行,它既不是进程也不是线程

Service的生命周期

这里写图片描述

使用context.startService() 启动Service

其生命周期为context.startService() ->onCreate()- >onStart()->Service running–>(如果调用context.stopService() )->onDestroy() ->Service shut down

如果Service还没有运行,则android先调用onCreate()然后调用onStart();
如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。

调用stopService的时候直接onDestroy,
如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。
该Service的调用者再启动起来后可以通过stopService关闭Service。

所以调用startService的生命周期为:onCreate –> onStart(可多次调用) –> onDestroy

对于bindService()启动Service会经历:
context.bindService()->onCreate()->onBind()->Service running–>onUnbind() -> onDestroy() ->Service stop

onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。
这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,
Srevice就会调用onUnbind->onDestroy相应退出。

所以调用bindService的生命周期为:onCreate –> onBind(只一次,不可多次绑定) –> onUnbind –> onDestory。
一但销毁activity它就结束,如果按home把它放到后台,那他就不退出。

Service的使用:

MyService.java 代码如下

public class MyService extends Service {  

    public static final String TAG = "MyService";  

    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  

    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  

    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  

    @Override  
    public IBinder onBind(Intent intent) {  
        return null;  
    }  

}  

MainActivity.java 代码如下

public class MainActivity extends Activity implements OnClickListener {  

    private Button startService;  

    private Button stopService;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        startService = (Button) findViewById(R.id.start_service);  
        stopService = (Button) findViewById(R.id.stop_service);  
        startService.setOnClickListener(this);  
        stopService.setOnClickListener(this);  
    }  

    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.start_service:  
            Intent startIntent = new Intent(this, MyService.class);  
            startService(startIntent);  
            break;  
        case R.id.stop_service:  
            Intent stopIntent = new Intent(this, MyService.class);  
            stopService(stopIntent);  
            break;  
        default:  
            break;  
        }  
    }  

}  

需要在AndroidManifest.xml注册

<service android:name="android.geekband004.MyService"/>

Service 与 Activity通信

MyService.java 代码如下

public class MyService extends Service {  

    public static final String TAG = "MyService";  

    private MyBinder mBinder = new MyBinder();  

    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  

    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  

    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  

    @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  

    class MyBinder extends Binder {  
        public MyService getService() {  
            return MyService.this;
        }  
    }  
}  

MainActivity.java 代码如下

public class MainActivity extends Activity implements OnClickListener {  

    private Button startService;  

    private Button stopService;  

    private Button bindService;  

    private Button unbindService;  

    private MyService.MyBinder myBinder;  

    private MyService myService;

    private ServiceConnection connection = new ServiceConnection() {  

        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  

        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myBinder = (MyService.MyBinder) service;  
            myService = myBinder.getService();  
        }  
    };  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        startService = (Button) findViewById(R.id.start_service);  
        stopService = (Button) findViewById(R.id.stop_service);  
        bindService = (Button) findViewById(R.id.bind_service);  
        unbindService = (Button) findViewById(R.id.unbind_service);  
        startService.setOnClickListener(this);  
        stopService.setOnClickListener(this);  
        bindService.setOnClickListener(this);  
        unbindService.setOnClickListener(this);  
    }  

    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.start_service:  
            Intent startIntent = new Intent(this, MyService.class);  
            startService(startIntent);  
            break;  
        case R.id.stop_service:  
            Intent stopIntent = new Intent(this, MyService.class);  
            stopService(stopIntent);  
            break;  
        case R.id.bind_service:  
            Intent bindIntent = new Intent(this, MyService.class);  
            bindService(bindIntent, connection, BIND_AUTO_CREATE);  
            break;  
        case R.id.unbind_service:  
            unbindService(connection);  
            break;  
        default:  
            break;  
        }  
    }  

}  

这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又得到了MyBinder的实例,以及MyService 的实例。

BroadcastReceiver

什么是BroadcastReceiver

在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。

下面将详细的阐述如何发送Broadcast和使用BroadcastReceiver过滤接收的过程:

  首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调用 sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。

  当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若匹配则就会调用BroadcastReceiver的onReceive()方法。所以当我们定义一个BroadcastReceiver的时候,都需要实现onReceive()方法。

注册BroadcastReceiver有两种方式:

静态注册:在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器。

<receiver android:name="myRecevicer">   
    <intent-filter>    
      <action android:name="com.dragon.net"></action> 
      </intent-filter>
</receiver> 

动态注册:

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(String);
registerReceiver(BroadcastReceiver,intentFilter);

WebView

Android提供了WebView控件展示web页面的能力

mWebView = (WebView) findViewById(R.id.WebView);  
mWebView.getSettings().setJavaScriptEnabled(true);  
mWebView.loadUrl("http://www.baidu.com");  

Widget

什么是Widget

Widget是应用程序窗口小部件(Widget)是微型的应用程序视图,它可以被嵌入到其它应用程序中(比如桌面)并接收周期性的更新。你可以通过一个App Widget Provider来发布一个Widget。

AppWidgetProvider 继承自 BroadcastReceiver,它能接收 widget 相关的广播,例如 widget 的更新、删除、开启和禁用等。

Widget函数

AppWidgetProvider中的广播处理函数如下:

onUpdate()
当 widget 更新时被执行。
同样,当用户首次添加 widget 时,onUpdate() 也会被调用,这样 widget 就能进行必要的设置工作(如果需要的话) 。但是,如果定义了 widget 的 configure属性(即android:config,后面会介绍),那么当用户首次添加 widget 时,onUpdate()不会被调用;之后更新 widget 时,onUpdate才会被调用。

onDeleted(Context, int[])
当 widget 被删除时被触发。

onEnabled(Context)
当第1个 widget 的实例被创建时触发。也就是说,如果用户对同一个 widget 增加了两次(两个实例),那么onEnabled()只会在第一次增加widget时触发。

onDisabled(Context)
当最后1个 widget 的实例被删除时触发。

onReceive(Context, Intent)
接收到任意广播时触发,并且会在上述的方法之前被调用。

Widget支持的布局和控件

Widget并不支持所有的布局和控件,而仅仅只是支持Android布局和控件的一个子集。
App Widget支持的布局:
- FrameLayout
- LinearLayout
- RelativeLayout
- GridLayout
App Widget支持的控件:
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextView
- ViewFlipper
- ListView
- GridView
- StackView
- AdapterViewFlipper

首先需要在Androidmanifest.xml文件代码定义窗口小部件(类似广播的静态注册):

<receiver android:name=".MusicWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
                <action android:name="android.geekband004.controlMusic" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@layout/widget_music">
            </meta-data>
        </receiver>

其中需要在res/layout目录下新建一个widget_music.xml代码文件定义appwidget-provider相关属性:

<?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:minHeight="140dp"
    android:minWidth="140dp"
    android:previewImage="@mipmap/ic_launcher"
    android:initialLayout="@layout/layout_widget"
    >
</appwidget-provider>

自己写一个类继承自AppWidgetProvider:

public class MusicWidget extends AppWidgetProvider {

    @Override
    public void onEnabled(Context context) {
        Log.d("enabled", "enable");
        super.onEnabled(context);
    }

    @Override
    public void onDisabled(Context context) {
        Log.d("disabled", "disable");
        super.onDisabled(context);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("onReceive", "onReceive");
        super.onReceive(context, intent);

    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
//        Log.d("appWidgetIds",String.valueOf(appWidgetIds));
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.layout_widget);

        Intent intent = new Intent();
        intent.setAction(MainActivity.ANDROID_GEEKBAND004_CONTROLMUSIC);

        // set start button listener
        intent.putExtra(MainActivity.CHOICE_CODE, MainActivity.START_MUSIC_CODE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,MainActivity.START_MUSIC_CODE,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_start_button,pendingIntent);

        // set pause button listener
        intent.putExtra(MainActivity.CHOICE_CODE, MainActivity.PAUSE_MUSIC_CODE);
        pendingIntent = PendingIntent.getBroadcast(context,MainActivity.PAUSE_MUSIC_CODE,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_pause_button,pendingIntent);

        // set last button listener
        intent.putExtra(MainActivity.CHOICE_CODE, MainActivity.LAST_MUSIC_CODE);
        pendingIntent = PendingIntent.getBroadcast(context,MainActivity.LAST_MUSIC_CODE,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_last_button,pendingIntent);

        // set next button listener
        intent.putExtra(MainActivity.CHOICE_CODE, MainActivity.NEXT_MUSIC_CODE);
        pendingIntent = PendingIntent.getBroadcast(context,MainActivity.NEXT_MUSIC_CODE,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.widget_next_button,pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
    }
}

一般的,重写AppWidget里面的onReceive方法,用以后面的更新操作。
AppWidget的onUpdate里面完成view事件的初始化操作,在AppWidget里面,由于窗口小部件与本地代码运行在不同的进程空间,所以只能通过RemoteViews处理与相关view绑定的事件响应。
本例的RemoteViews需要的布局文件在res/layout下的layout_widget.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/control_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/song_name"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:maxLines="1"
        android:text="@string/app_name"/>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/song_name">

        <ImageButton
            android:id="@+id/widget_last_button"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@mipmap/ic_skip_previous_black_24dp"/>
        <ImageButton
            android:id="@+id/widget_start_button"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@mipmap/ic_play_arrow_black_24dp"
            android:layout_toRightOf="@+id/widget_last_button"/>
        <ImageButton
            android:id="@+id/widget_pause_button"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@mipmap/ic_pause_black_24dp"
            android:layout_toRightOf="@+id/widget_last_button"
            android:visibility="invisible"/>
        <ImageButton
            android:id="@+id/widget_next_button"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@mipmap/ic_skip_next_black_24dp"
            android:layout_toRightOf="@+id/widget_start_button"/>

    </RelativeLayout>


</RelativeLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值