四大组件之Service记录

  根据广大程序员经验,初学者请告别Eclipse,拥抱Android Studio!   原因:   1. 未来是Android Studio的天下(Google自己出品)。   2. Eclipse的配置和相关安装可以磨灭初学者一半的耐心,简直是拦路虎。(比如和我一样做类似题目毕设的同学已经哭晕在厕所)   3. 促使你换一台高配电脑。(心累,Android Studio在垃圾本上跑,几分钟编译一次,卡到怀疑人生,其实垃圾本四年前还是一条能跑lol的好本本,岁月催laptop老)

Android sdk文件夹到了80几G…撑爆了我的硬盘……电脑里装的软件过于多了…趁着五一大好春光(下雨)都给卸载了!包括毕设用的eclipse和各种版本的VS,以及以前用过现在用的少的各种专业软件(每一个都是10G大户)。不过我还是毅然留下了常年没有玩耍的游戏们(加起来也才80多G!相比之下,sdk里都放了些什么!)。

  但毕设是要做的。   所以Android套装们需要重新下载下来,当年安装的时候,对JDK、SDK、ADT这种东西一点儿不了解,现在重新来一遍。 这几天写了一些文字,但不能发上来,因为放入我的毕业论文里了。

------------------------废话终结线------------------------

Service生命周期

Service生命周期

注意

  • 运行在主线程,不能用它做耗时的请求或动作
  • 可在服务中开一个线程,在线程中做耗时动作

两种方式(本地服务)

Start方式:

  • 服务跟启动页没有任何联系
  • 无法得到服务对象

Bind方式(支持数据回传):

  • 通过Ibinder接口实例,返回一个ServiceConnection对象给启动源。
  • 通过ServiceConnection对象的相关方法可以得到Service对象

Start启动

activity_main.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<LinearLayout 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:orientation="vertical"
    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.abc.service.MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start:" />

    <Button
        android:id="@+id/start"
        android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="StartService" />

    <Button
        android:id="@+id/stop"
        android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="StopService" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Bind:" />

    <Button
        android:id="@+id/bind"
         android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="BindService" />

    <Button
        android:id="@+id/play"
        android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="播放" />

    <Button
        android:id="@+id/pause"
        android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="暂停" />

    <Button
        android:id="@+id/next"
         android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下一首" />

    <Button
        android:id="@+id/pervious"
        android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="上一首" />

    <Button
        android:id="@+id/unbind"
        android:onClick="doClick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="UnBindService" />

</LinearLayout>

如图。

样式

MainActivity.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.abc.service;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends Activity {
	Intent intent1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void doClick(View v) {
		switch (v.getId()) {
		case R.id.start:
			intent1 = new Intent(MainActivity.this, MyStartService.class);
			startService(intent1);
			break;
		case R.id.stop:
			stopService(intent1);
			break;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

MyStartService.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.abc.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyStartService extends Service {
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i("info", "Service--onCreate()");
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i("info", "Service--onStartCommand()");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i("info", "Service--onDestroy()");
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.i("info", "Service--onBind()");
		return null;
	}

}

注册

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.abc.service"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="25" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.abc.service.MyStartService"></service>
    </application>

</manifest>

可在LogCat中看到执行情况。

Bind启动

注册新类

1
 <service android:name="com.abc.service.MyBindService"></service>

MyBindService.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.abc.service;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyBindService extends Service {
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}

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

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.i("info", "onBind--onCreate()");
		return new MyBinder();
	}

	@Override
	public void unbindService(ServiceConnection conn) {
		// TODO Auto-generated method stub
		Log.i("info", "BindService--unbindService()");
		super.unbindService(conn);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i("info", "BindService--onDestroy()");
		super.onDestroy();
	}

	public void Play() {
		Log.i("info", "播放");
	}

	public void Pause() {
		Log.i("info", "暂停");
	}

	public void Pervious() {
		Log.i("info", "上一首");
	}

	public void next() {
		Log.i("info", "下一首");
	}
}

MainActivity.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.abc.service;

import com.abc.service.MyBindService.MyBinder;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends Activity {
	Intent intent1;
	Intent intent2;
	MyBindService service;
	ServiceConnection conn = new ServiceConnection() {

		@Override // 当启动源跟Service的连接意外丢失的时候会调用这个方法
		// 比如当Service崩溃了或者被强行杀死了
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub

		}

		@Override // 当启动页跟Service成功连接之后将会在自动调用这个方法
		public void onServiceConnected(ComponentName name, IBinder binder) {
			// TODO Auto-generated method stub
			service = ((MyBinder) binder).getService();
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void doClick(View v) {
		switch (v.getId()) {
		case R.id.start:
			intent1 = new Intent(MainActivity.this, MyStartService.class);
			startService(intent1);
			break;

		case R.id.stop:
			stopService(intent1);
			break;

		case R.id.play:
			service.Play();
			break;

		case R.id.pause:
			service.Pause();
			break;

		case R.id.pervious:
			service.Pervious();
			break;

		case R.id.next:
			service.next();
			break;

		case R.id.bind:
			intent2 = new Intent(MainActivity.this, MyBindService.class);
			bindService(intent2, conn, Service.BIND_AUTO_CREATE);
			break;

		case R.id.unbind:
			unbindService(conn);
			break;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

UnBindService只能点击一次,否则会报错。

两种方法混用

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
package com.abc.service;

import com.abc.service.MyBindService.MyBinder;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends Activity {
	Intent intent1;
	Intent intent2;
	MyBindService service;
	ServiceConnection conn = new ServiceConnection() {

		@Override // 当启动源跟Service的连接意外丢失的时候会调用这个方法
		// 比如当Service崩溃了或者被强行杀死了
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub

		}

		@Override // 当启动页跟Service成功连接之后将会在自动调用这个方法
		public void onServiceConnected(ComponentName name, IBinder binder) {
			// TODO Auto-generated method stub
			service = ((MyBinder) binder).getService();
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void doClick(View v) {
		switch (v.getId()) {
		case R.id.start:
			intent1 = new Intent(MainActivity.this, MyStartService.class);
			startService(intent1);
			break;

		case R.id.stop:
			stopService(intent1);
			break;

		case R.id.play:
			service.Play();
			break;

		case R.id.pause:
			service.Pause();
			break;

		case R.id.pervious:
			service.Pervious();
			break;

		case R.id.next:
			service.next();
			break;

		case R.id.bind:
			intent2 = new Intent(MainActivity.this, MyBindService.class);
			startService(intent2);
			bindService(intent2, conn, Service.BIND_AUTO_CREATE);
			break;

		case R.id.unbind:
			unbindService(conn);
			break;
		}
	}
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		stopService(intent2);
		unbindService(conn);
		super.onDestroy();
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}
使用 Hugo 构建
主题 StackJimmy 设计