对service的4个问题的回答

1.Service的start和bind状态有什么区别?

2.同一个service,先start然后bindService,如何把它停止调?

3.serviceCommand方法的返回值的不同含义是什么?

4.service的生命周期方法onCreate,onStart,onBind等运行在哪个线程?

1

start和启动它的组件没有关系,它有自己独立的生命周期,而bindService这个service依赖于这些组件,当这些组件全部销毁候,service也随之销毁。

多次调用start方法,start方法会多次被回调,多次调用bind,bind只会执行一次。

start开启的servic必须stopService或者stopSelf后停止,bind的service可以用unbind去停止服务、

2

stopService和每个绑定它的组件unBindService,最后一个stopService或者unBindService会导致service destroy.

3

/**
 * Bits returned by {@link #onStartCommand} describing how to continue
 * the service if it is killed.  May be {@link #START_STICKY},
 * {@link #START_NOT_STICKY}, {@link #START_REDELIVER_INTENT},
 * or {@link #START_STICKY_COMPATIBILITY}.
 */
public static final int START_CONTINUATION_MASK = 0xf;

/**
 * Constant to return from {@link #onStartCommand}: compatibility
 * version of {@link #START_STICKY} that does not guarantee that
 * {@link #onStartCommand} will be called again after being killed.
 */
public static final int START_STICKY_COMPATIBILITY = 0;

/**
 * Constant to return from {@link #onStartCommand}: if this service's
 * process is killed while it is started (after returning from
 * {@link #onStartCommand}), then leave it in the started state but
 * don't retain this delivered intent.  Later the system will try to
 * re-create the service.  Because it is in the started state, it will
 * guarantee to call {@link #onStartCommand} after creating the new
 * service instance; if there are not any pending start commands to be
 * delivered to the service, it will be called with a null intent
 * object, so you must take care to check for this.
 * 
 * <p>This mode makes sense for things that will be explicitly started
 * and stopped to run for arbitrary periods of time, such as a service
 * performing background music playback.
 */
public static final int START_STICKY = 1;

/**
 * Constant to return from {@link #onStartCommand}: if this service's
 * process is killed while it is started (after returning from
 * {@link #onStartCommand}), and there are no new start intents to
 * deliver to it, then take the service out of the started state and
 * don't recreate until a future explicit call to
 * {@link Context#startService Context.startService(Intent)}.  The
 * service will not receive a {@link #onStartCommand(Intent, int, int)}
 * call with a null Intent because it will not be re-started if there
 * are no pending Intents to deliver.
 * 
 * <p>This mode makes sense for things that want to do some work as a
 * result of being started, but can be stopped when under memory pressure
 * and will explicit start themselves again later to do more work.  An
 * example of such a service would be one that polls for data from
 * a server: it could schedule an alarm to poll every N minutes by having
 * the alarm start its service.  When its {@link #onStartCommand} is
 * called from the alarm, it schedules a new alarm for N minutes later,
 * and spawns a thread to do its networking.  If its process is killed
 * while doing that check, the service will not be restarted until the
 * alarm goes off.
 */
public static final int START_NOT_STICKY = 2;

/**
 * Constant to return from {@link #onStartCommand}: if this service's
 * process is killed while it is started (after returning from
 * {@link #onStartCommand}), then it will be scheduled for a restart
 * and the last delivered Intent re-delivered to it again via
 * {@link #onStartCommand}.  This Intent will remain scheduled for
 * redelivery until the service calls {@link #stopSelf(int)} with the
 * start ID provided to {@link #onStartCommand}.  The
 * service will not receive a {@link #onStartCommand(Intent, int, int)}
 * call with a null Intent because it will will only be re-started if
 * it is not finished processing all Intents sent to it (and any such
 * pending events will be delivered at the point of restart).
 */
public static final int START_REDELIVER_INTENT = 3;

4

运行在主线程中

下面是我学习用aidl写的一个start和bind service的一个示例

// Book1.aidl
package com.example.administrator.myaidl.aidl;

// Declare any non-default types here with import statements

parcelable Book;
package com.example.administrator.myaidl.aidl;
import com.example.administrator.myaidl.aidl.Book;

// Declare any non-default types here with import statements

interface IBookArrivedListener {
   void onNewBookArrived(in Book book);
}
package com.example.administrator.myaidl.aidl;

// Declare any non-default types here with import statements
import com.example.administrator.myaidl.aidl.Book;
import com.example.administrator.myaidl.aidl.IBookArrivedListener;

interface IBookManager {
    List<Book> getBookList();
    void addBook(in Book book);
    void registerNewBookArrivedListener(in IBookArrivedListener bookArrivedListenre);
    void unRegisterNewBookArrivedListener(in IBookArrivedListener bookArrivedListenre);
}
package com.example.administrator.myaidl.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable{
    public int bookId;
    public String bookName;

    public Book(int bookId,String bookName){
        this.bookId = bookId;
        this.bookName = bookName;
    }
    protected Book(Parcel in) {
        bookId = in.readInt();
        bookName= in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(bookId);
        dest.writeString(bookName);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    @Override
    public String toString() {
        return "bookName = " +bookName + "bookId = " + bookId;
    }
}
public class MainActivity extends AppCompatActivity {
    public static final String TAG ="XCR_MainActivity";
    private TextView mTextView;
    private Context mContext;
    Intent intent;
    int i = 0;
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG,"service name :" + service);
            IBookManager iBookManager = IBookManager.Stub.asInterface(service);
            try {
//                iBookManager.addBook(new Book(1,"ANDROID"));
                List<Book> books = iBookManager.getBookList();
                Log.d(MainActivity.TAG,"books.size() =" + books.size());
                iBookManager.registerNewBookArrivedListener(new IBookArrivedListener.Stub() {

                    @Override
                    public void onNewBookArrived(Book book) throws RemoteException {
                        Log.d(MainActivity.TAG,"receive book info ,book = " + book.toString());
                    }
                });
            } catch (RemoteException e) {
                Log.e(MainActivity.TAG,e.getMessage());
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(MainActivity.TAG,"main onCreate" + Thread.currentThread());
        setContentView(R.layout.activity_main);
        mTextView =(TextView) findViewById(R.id.textView);
        mContext = this;
        mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                i ++;
                intent = new Intent(mContext,MyService.class);
                mContext.bindService(intent,mServiceConnection,BIND_AUTO_CREATE);
//                mContext.startService(intent);
                if(i > 1){
                    mContext.unbindService(mServiceConnection);
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"ACTIVITY onDestroy");
//        mContext.unbindService(mServiceConnection);
        mContext.stopService(intent);
    }
}
public class MyService extends Service{
    private CopyOnWriteArrayList<Book> mBooksList =new CopyOnWriteArrayList<>();
    private IBookArrivedListener mIBookArrivedListener;
    private AtomicBoolean isUnbindService = new AtomicBoolean(false);

    private IBinder mIBinder = new IBookManager.Stub(){

        @Override
        public List<Book> getBookList() throws RemoteException {
            return mBooksList;

        }

        @Override
        public void addBook(Book book) throws RemoteException {
            mBooksList.add(book);
            Log.d(MainActivity.TAG,"book.toString()= " + book.toString());

        }

        @Override
        public void registerNewBookArrivedListener(IBookArrivedListener bookArrivedListenre) throws RemoteException {
            mIBookArrivedListener = bookArrivedListenre;
        }

        @Override
        public void unRegisterNewBookArrivedListener(IBookArrivedListener bookArrivedListenre) throws RemoteException {
            mIBookArrivedListener = null;
        }
    };
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(MainActivity.TAG,"onBind");
        Log.d(MainActivity.TAG,"service onBind" + Thread.currentThread());
        return mIBinder;
    }

    @Override
    public void onCreate() {
        Log.d(MainActivity.TAG,"service onCreate" + Thread.currentThread());
        Log.d("XCR_MainActivity","onCreate" );
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while(!isUnbindService.get()){
                    i++;
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        Log.e(MainActivity.TAG,e.getMessage());
                    }
                    Book book = new Book(i,"android" + i);
                    if(!mBooksList.contains(book)) {
                        mBooksList.add(book);
                        Log.d("XCR_MainActivity","mBooksList.size()= " +mBooksList.size());
                        try {
                            if(null != mIBookArrivedListener) {
                                mIBookArrivedListener.onNewBookArrived(book);
                            }
                        } catch (RemoteException e) {
                            Log.e("XCR_MainActivity",e.getMessage());
                        }
                    }

                }
            }
        }).start();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(MainActivity.TAG,"onStartCommand" + Thread.currentThread());
        return 3;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(MainActivity.TAG,"onUnbind" + Thread.currentThread());
        Log.d(MainActivity.TAG,"onUnbind");
        return true;
    }

    @Override
    public void onDestroy() {
        Log.d(MainActivity.TAG,"onDestroy" + Thread.currentThread());
        super.onDestroy();
        isUnbindService.set(true);
        Log.d(MainActivity.TAG,"SERVICE onDestroy");
    }
}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.administrator.myaidl.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:text="Hello World!"
        android:id="@+id/textView"
        />
</RelativeLayout>

log如下:

07-08 23:15:11.205 2848-2848/com.example.administrator.myaidl D/XCR_MainActivity: main onCreateThread[main,5,main]
07-08 23:15:30.442 3043-3043/? D/XCR_MainActivity: service onCreateThread[main,5,main]
07-08 23:15:30.442 3043-3043/? D/XCR_MainActivity: onCreate
07-08 23:15:30.444 3043-3043/? D/XCR_MainActivity: onBind
07-08 23:15:30.444 3043-3043/? D/XCR_MainActivity: service onBindThread[main,5,main]
07-08 23:15:30.446 2848-2848/com.example.administrator.myaidl D/XCR_MainActivity: service name :android.os.BinderProxy@26932a95
07-08 23:15:30.458 2848-2848/com.example.administrator.myaidl D/XCR_MainActivity: books.size() =0
07-08 23:15:35.460 3043-3066/com.example.administrator.myaidl:remote D/XCR_MainActivity: mBooksList.size()= 1
07-08 23:15:35.461 2848-2869/com.example.administrator.myaidl D/XCR_MainActivity: receive book info ,book = bookName = android1bookId = 1
07-08 23:15:40.462 3043-3066/com.example.administrator.myaidl:remote D/XCR_MainActivity: mBooksList.size()= 2
07-08 23:15:40.463 2848-2870/com.example.administrator.myaidl D/XCR_MainActivity: receive book info ,book = bookName = android2bookId = 2
07-08 23:15:45.463 3043-3066/com.example.administrator.myaidl:remote D/XCR_MainActivity: mBooksList.size()= 3
07-08 23:15:45.464 2848-2869/com.example.administrator.myaidl D/XCR_MainActivity: receive book info ,book = bookName = android3bookId = 3
07-08 23:15:45.634 3043-3043/com.example.administrator.myaidl:remote D/XCR_MainActivity: onUnbindThread[main,5,main]
07-08 23:15:45.635 3043-3043/com.example.administrator.myaidl:remote D/XCR_MainActivity: onUnbind
07-08 23:15:45.636 3043-3043/com.example.administrator.myaidl:remote D/XCR_MainActivity: onDestroyThread[main,5,main]
07-08 23:15:45.636 3043-3043/com.example.administrator.myaidl:remote D/XCR_MainActivity: SERVICE onDestroy
07-08 23:15:50.466 3043-3066/com.example.administrator.myaidl:remote D/XCR_MainActivity: mBooksList.size()= 4
07-08 23:15:50.467 2848-2870/com.example.administrator.myaidl D/XCR_MainActivity: receive book info ,book = bookName = android4bookId = 4
07-08 23:15:55.871 2848-2848/com.example.administrator.myaidl D/XCR_MainActivity: ACTIVITY onDestroy

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值