Android Service服务
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(); ?>