Android studio 工程
第一步,創建一個工程,建立一個簡單的service
1.我們工程創建完畢,接下來進入到
MainActivity
里面,在當前包下右鍵創建一個類,繼承自Service,具體的操作我們截圖了,看截圖怎么創建,只是新手操作的,
在創建好的工程基礎上進行如下操作
右鍵包名
我們創建一個自定義action的service
這里兩種Service 為什么我們選擇第一種
其實這個地方我也了解的不是很深入,
- 第二種我們可以在AndroidMainfest.xml 指定Intent-filter里面的action name 因為系統服務很多,簡單來說也就是指定一個匹配名字,知道我們當前需要用哪一個服務,是需要在使用時綁定的,使用bindService
- 第一種的那個我們一般是直接使用startService(intent),啟動服務的,這兩種具體怎么區分我也不是很清楚,待后面仔細研究一下,我的簡單理解就是所管理的生命周期不一樣,
自己定義使用的服務類
接下來我們看下服務類怎么寫,這里還有一步,別忘了,就是在配置文件
添加,創建好之后這個要手動添加一下action,來給我們的服務起個名字
<application android:allowBackup="true"
android:icon="@mipmap/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="my.teco.plee.sigalton.MsgService"
android:enabled="true"
android:permission="my.teco.plee.sigalton.MsgService">
<intent-filter> <action
android:name="my.teco.plee.sigalton.MSG_ACTION"></action>
</intent-filter>
</service>
</application>
這里寫代碼了
public class MsgService extends Service {
/**
* 進度條的最大值
*/
public static final int MAX_PROGRESS_VALUE = 100;
/**
* 進度條的進度值
*/
private int progress = 0;
//下面這句話是第二種方法,用通知
private Intent intent = new Intent("my.teco.plee.sigalton.RECEIVER");
//下面這個是使用第一種方法
/**
* 更新進度的回調接口
*/
private OnProgressListener onProgressListener;
/**
* 注冊回調接口的方法,供外部調用
*/
public void setOnProgressListener(OnProgressListener onProgressListener){
//獲取傳入的接口對象
this.onProgressListener = onProgressListener;
}
/**
* 增加get() 方法,供Activity調用
*
* @return 下載進度
*/
public int getProgress() {
return progress;
}
/**
* 模擬下載任務,每秒鐘更新一次
*/
public void startDownLoad() {
new Thread(new Runnable() {
@Override
public void run() {
while (progress < MAX_PROGRESS_VALUE) {
progress += 5;
//發送Action為my.teco.plee.sigalton.RECEIVER
intent.putExtra("progress",progress);
sendBroadcast(intent);//
//進度條發生變化通知方法//
if (onProgressListener !=null){//
onProgressListener.onProgress(progress);//
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();//開啟
}
public MsgService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startDownLoad();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//如果使用第一種方法的話需要下面這樣寫
// return new MsgBinder();
//第二種方法需要寫成下面
return null;
// throw new UnsupportedOperationException("Not yet implemented");
}
//返回綁定服務返回的實例
public class MsgBinder extends Binder{
/**
* 獲取當前Service的實例
* @return
*/
public MsgService getService(){
return MsgService.this;
}
}}
MainActivity 我們的代碼,第一種方法,
public class MainActivity extends AppCompatActivity {
private MsgService msgService;
private int progress = 0;
private ProgressBar mProgressBar;
private MsgReceiver msgReceiver;
private Intent mIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//
SharePreferenceClass.getInstance().getClass();
//綁定Service 第一種方法 ,如果使用第二種方法注釋下面這兩句
Intent intent = new Intent("my.teco.plee.sigalton.MSG_ACTION");
bindService(intent,connection, Context.BIND_AUTO_CREATE);
//第二種方法,打開下面的廣播接收器
//動態注冊廣播接收器
// msgReceiver = new MsgReceiver();
// IntentFilter intentFilter = new IntentFilter();
// intentFilter.addAction("my.teco.plee.sigalton.RECEIVER");
// registerReceiver(msgReceiver, intentFilter);
mProgressBar = (ProgressBar) findViewById(R.id.progessBar1);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//下面是第一種方法,每次我們只能使用一個
//開始下載
msgService.startDownLoad();
//監聽進度
listenProgress();
//下面是第二種形式啟動service,我們先注釋掉
//啟動服務
// mIntent = new Intent("my.teco.plee.sigalton.MSG_ACTION");
// startService(mIntent);
}
});
}
/**
* 監聽進度,每秒獲取調用MsgService 的getPress方法來獲取進度,更新UI
*/
public void listenProgress() {
new Thread(new Runnable() {
@Override
public void run() {
while (progress < MsgService.MAX_PROGRESS_VALUE) {
progress = msgService.getProgress();
mProgressBar.setProgress(progress);
System.out.println(progress+"我");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
//第一種方法使用下面這個
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder
service) {
//返回一個MsgService對象
msgService = ((MsgService.MsgBinder) service).getService();
//注冊回調接口來接受下載進度的變化
//msgService 相當于Class B,Activity 相當于Class a ,
// setOnProgressListener相當于方法C,A調用B類的方法C,C方法的參數中有接口。
// 傳入方法C中的接口要實現接口中的方法。
msgService.setOnProgressListener(new
OnProgressListener() {
@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);
}
});
System.out.println("我已經連接了");
}
@Override
public void onServiceDisconnected(ComponentName name) {
} };
@Override
protected void onDestroy() {
super.onDestroy();
//停止服務
unbindService(connection);
//注銷廣播 第二種在寫這個,
unregisterReceiver(msgReceiver);
}
// 第二種方法使用下面的
/**
* 廣播接受器
*/
public class MsgReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//拿到進度
int progress = intent.getIntExtra("progress",0);
mProgressBar.setProgress(progress);
System.out.println(progress + "我");
}
}}
我們貼上接口代碼
public interface OnProgressListener {
void onProgress(int progress);}
}
最后我們看一下工程目錄結構
看圖上代碼結構進行配置工程
以上是使用service ,進行簡單的計數,第一種是使用回調,第二種是使用通知更新