Service是Android系統中提供的四大組件之一。它是運行在後臺的一種服務,一般聲明週期較長,不直接與用戶進行交互。
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啓動服務。這兩個方法都可以啓動Service,但是它們的使用場合有所不同。
1. 使用startService()方法啓用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。
如果打算採用Context.startService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接着調用onStart()方法。
如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStart()方法。
採用startService()方法啓動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。
1. 使用startService()方法啓用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。
如果打算採用Context.startService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接着調用onStart()方法。
如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStart()方法。
採用startService()方法啓動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。
2. 使用bindService()方法啓用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。
onBind()只有採用Context.bindService()方法啓動服務時纔會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法並不會導致該方法被多次調用。
採用Context.bindService()方法啓動服務時只能調用onUnbind()方法解除調用者與服務解除,服務結束時會調用onDestroy()方法。
onBind()只有採用Context.bindService()方法啓動服務時纔會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法並不會導致該方法被多次調用。
採用Context.bindService()方法啓動服務時只能調用onUnbind()方法解除調用者與服務解除,服務結束時會調用onDestroy()方法。
這裏我採用了第一種方法啓動 startService(new Intent(this, LocalService.class));不過首先需要在AndroidManifest.xml文件中註冊聲明我們新建的Service,在application標籤內添加 <service android:name=".LocalService" />即可。
下面是實現的方法,開啓新線程,每隔一分鐘從服務器獲取消息,若產生消息,則在手機狀態欄通知該消息。
public class LocalService extends Service {
private static String info = null;
private String TAG = "localservice";// 定義打印信息標識
private NotificationManager mNM;// 定義狀態欄通知
private final IBinder mBinder = new LocalBinder();// 實例化LocalBinder
// public static native void getSqlInfo();
public class LocalBinder extends Binder {
LocalService getService() {
return LocalService.this;
}
}
public IBinder onBind(Intent intent) {
Log.i(TAG, "this is onBind");
return mBinder;
}
// 實現創建方法
public void onCreate() {
Log.i(TAG, "this is onCreate");
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// 獲取通知欄管理器
}
// 實現開始方法
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "received start id" + startId + ":" + intent);
// 開啓線程
MessageThread messageThread = new MessageThread();
messageThread.start();
return START_STICKY;
}
// 實現銷燬方法
public void onDestory() {
Log.i(TAG, "this is onDestory");
mNM.cancel("qqq", 0);
}
// 實現解除bind方法
public boolean onUnbind(Intent intent) {
Log.i(TAG, "this is onUnbind");
return super.onUnbind(intent);
}
private void showNotification(String serverMessage) {
int icon = R.drawable.icon; // 通知圖標
CharSequence tickerText = "local sevice has started" + serverMessage; // 狀態欄顯示的通知文本提示
long when = System.currentTimeMillis(); // 通知產生的時間,會在通知信息裏顯示
// 用上面的屬性初始化Nofification// 實例化狀態通知
Notification notification = new Notification(icon, tickerText, when);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, HelloPush.class), 0);// 定義通知欄單擊時間觸發的intent
notification.defaults |= Notification.DEFAULT_SOUND;// 添加聲音
// notification.defaults |= Notification.DEFAULT_VIBRATE;// 添加震動
notification.defaults |= Notification.DEFAULT_LIGHTS;// 添加LED燈提醒
notification.flags = Notification.FLAG_AUTO_CANCEL;// 在通知欄上點擊此通知後自動清除此通知
notification.setLatestEventInfo(this, "Local Service", tickerText,
contentIntent);// 設置該狀態欄通知消息的單擊事件
mNM.notify("qqq", 0, notification);// 通知欄顯示該通知
}
/**
* 從服務器端獲取消息
*
*/
class MessageThread extends Thread {
// 運行狀態,下一步驟有大用
public boolean isRunning = true;
@SuppressLint("SimpleDateFormat")
public void run() {
System.out.println("running++++++++++++++");
while (isRunning) {
try {
// 獲取服務器消息
String serverMessage = getServerMessage();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
Date curDate = new Date(System.currentTimeMillis());// 獲取當前時間
String str = formatter.format(curDate);
System.out.println("++++++++++++" + str);// &&str=="08:00"
if (serverMessage != null && !"".equals(serverMessage)
// &&"15:00".equalsIgnoreCase(str)
) {
showNotification(serverMessage);
}
// 休息1分鐘
System.out.println("sleeping now+++++");
Thread.sleep(60000);
System.out.println("sleep ended+++++");
} catch (InterruptedException e) {
System.out.println("thread sleep error++++");
e.printStackTrace();
}
}
}
}
/**
* @return 返回服務器要推送的消息,否則如果爲空的話,不推送
*/
public String getServerMessage() {
System.out.println("getServerMessage++++++++");
info = null;
// getSqlInfo();
// getSql();
info = connecting();
System.out.println("getServerMessage+++++++" + info);
return info;
}
// public static int ReturnInfo(final String title) {
// System.out.println("ReturnInfo+++++++++" + title);
// info = title;
// return 1;
// }
//
// public void getSql() {
// try {
// String url = "jdbc:mysql://192.168.1.104:80/test";
// String user = "root";
// String pwd = "";
//
// // 加載驅動,這一句也可寫爲:Class.forName("com.mysql.jdbc.Driver");
// Class.forName("com.mysql.jdbc.Driver").newInstance();
// // 建立到MySQL的連接
// Connection conn = DriverManager.getConnection(url, user, pwd);
//
// // 執行SQL語句
// java.sql.Statement stmt = conn.createStatement();// 創建語句對象,用以執行sql語言
// ResultSet rs = stmt.executeQuery("select * from push where id = 1");
//
// // 處理結果集
// while (rs.next()) {
// String name = rs.getString("name");
// info = name;
// System.out.println(name);
// }
// rs.close();// 關閉數據庫
// conn.close();
// } catch (Exception ex) {
// System.out.println("Error : " + ex.toString());
// }
// }
public String connecting() {
/* 存放http請求得到的結果 */
String result = "";
// String ss = null;
String name = null;
/* 將要發送的數據封包 */
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", "1"));
InputStream is = null;
// http post
try {
/* 創建一個HttpClient的一個對象 */
HttpClient httpclient = new DefaultHttpClient();
/* 創建一個HttpPost的對象 */
HttpPost httppost = new HttpPost(
"http://192.168.1.104:80/ying/yy.php");
/* 設置請求的數據 */
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
/* 創建HttpResponse對象 */
HttpResponse response = httpclient.execute(httppost);
/* 獲取這次迴應的消息實體 */
HttpEntity entity = response.getEntity();
/* 創建一個指向對象實體的數據流 */
is = entity.getContent();
} catch (Exception e) {
System.out.println("Connectiong Error");
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "/n");
}
is.close();
result = sb.toString();
System.out.println("get = " + result);
} catch (Exception e) {
System.out.println("Error converting to String");
}
// parse json data
try {
/* 從字符串result創建一個JSONArray對象 */
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
System.out.println("Success");
System.out.println("result " + json_data.toString());
// ct_id=json_data.getInt("id");
name = json_data.getString("name");
// if (i == 0) {
// ss = json_data.toString();
// } else {
// ss += json_data.toString();
// }
}
} catch (JSONException e) {
System.out.println("Error parsing json");
}
return name;
}
}
下面是php代碼<?php
require_once("conn.php");
session_start();
$q=mysql_query("SELECT name FROM push WHERE id='".$_REQUEST['id']."'");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
?>