android学习笔记---40_建立能与访问者进行相互通信的本地服务,后台运行的service

本文介绍Android中服务与Activity之间的通信机制,重点讲解如何利用IBinder实现本地服务的绑定与数据交换,包括服务端与客户端的具体实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

40_建立能与访问者进行相互通信的本地服务

-------------------------------------------
1.本地服务:如果服务和访问者在一个进程中那么就叫做本地服务。
  远程服务:如果服务和访问者不在同一个应用,那么这就叫做远程服务。
-----------------------------------------------------------------------
2.通过startService()和stopService()启动关闭服务。适用于服务和Activity之间没有调用交互的情况。
  如果相互之间需要方法调用或者传递参数,需要使用bindService()和unbindService()方法启动关闭服务。

采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法,这个时候调用者和服务绑定在一

起。 如果客户端要与服务进行通信,那么,onBind()方法必须返回Ibinder对象。如果调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用

onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()

方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()--

>onDestroy()方法。
------------------------------------------------------------------------------
Activity与服务进行通信,开发人员通常把通信方法定义在接口里,然后让Ibinder对象实现该接口,而Activity通过该接口引用服务onBind()方法返回的Ibinder

对象,然后调用Ibinder对象里自定义的通信方法。例子如下:

本例是一个本地服务,即服务与Activity在同一个应用内部。
----------------------------------------------------------
接口:
public interface ICountService {
 public int getCount();
}
服务类:
public class CountService extends Service {
private boolean quit;
private int count;
private ServiceBinder serviceBinder = new ServiceBinder();

public class ServiceBinder extends Binder implements ICountService {
 @Override
 public int getCount() {
  return count;
 }
}
@Override
public IBinder onBind(Intent intent) {
 return serviceBinder;
}
@Override
public void onCreate() {
 super.onCreate();
 new Thread(new Runnable() {
  @Override
  public void run() {
   while (!quit) {
       try {
    Thread.sleep(1000);
       } catch (InterruptedException e) {}
       count++;
   }
  }
 }).start();
}

@Override
public void onDestroy() {
 super.onDestroy();
 this.quit = true;
}
}
客户端Activity:
public class ClientActivity extends Activity {
 private ICountService countService;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  this.bindService(new Intent(this, CountService.class), this.serviceConnection, BIND_AUTO_CREATE);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  this.unbindService(serviceConnection);
 } 
 
 private ServiceConnection serviceConnection = new ServiceConnection() {
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   countService = (ICountService) service;//对于本地服务,获取的实例和服务onBind()返回的实例是同一个
   int i = countService.getCount();   
   Log.v("CountService", "Count is " + i);
  }
  @Override
  public void onServiceDisconnected(ComponentName name) {
   countService = null;
  }
 };
}
-----------------------------------------------------------------------------------------------------
2.a.下面是本地服务的例子:
    软件界面:有一个
    学号:
    text框
    查询按钮
 b.当点击查询按钮后,下面就会显示学生的名字
---------------------------------------------------
3.这个例子中采用activity作为服务的访问者。
----------------------------------------------
1.新建android项目:studentquery
2./studentquery/src/com/credream/stuquery/IStundent.java
   package com.credream.stuquery;

public interface IStundent {
 public String queryStudent(int no);
}
-----------------------------------------------------
3./studentquery/src/com/credream/stuquery/StudentqueryActivity.java
  package com.credream.stuquery;


import android.app.Activity;

import android.content.ComponentName;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

/**
 * 这个是访问者类,那么这个类如何访问服务中的query方法,以实现根据
 * 学生的学号得到学生的姓名呢?这里在service服务中的这个方法可以实现。
 *  

@Override
 public IBinder onBind(Intent intent) {
  return binder;
 }
 

 * 另外当使用方法bindService启动服务的时候,服务会给访问者也就是这个类,返回一个

 * IBinder对象给访问者,当访问者接收到IBinder这个对象后,就可以通过这个对象
 
* 调用服务中的方法。

 * -----------------------------------------------

 * 具体实现过程是这样的:当访问者(客户端)调用bindService方法启动服务的时候
 
* 服务就会自动调用onBind方法,取得IBinder对象,然后由操作系统,将IBinder

 * 对象传给客户端。客户端得到binder对象后,就可以通过得到的binder对象调用服务中的
 
* 方法
 
* @author xiaofeng
 *
 */

public class StudentqueryActivity extends Activity {
   
 private EditText studentno;
  
  private ServiceConnection conn = new StudentServiceConnection();
  
 private IStundent iStundent;
   
 private TextView resultView;
   
 @Override
   
 public void onCreate(Bundle savedInstanceState) {
  
      super.onCreate(savedInstanceState);
  
      setContentView(R.layout.main);
   
    
        resultView = (TextView) this.findViewById(R.id.resultView);
   
     studentno = (EditText) this.findViewById(R.id.studentno);
   
     Button button = (Button) this.findViewById(R.id.button);
     
   button.setOnClickListener(new ButtonClickListener());
    
    Intent service = new Intent(this, StudentService.class);
 
       bindService(service, conn, BIND_AUTO_CREATE);
     
   //BIND_AUTO_CREATE 值为1,意思是绑定了服务后就自动创建服务
  
  }
    
  
  private class StudentServiceConnection implements ServiceConnection{

 /**
 * Interface for monitoring the state of an application service. See Service and Context.bindService() for more information. 
Like

many callbacks from the system, the methods on this class are called from the main thread of your process. 
  */
   
  /**
    
  * 当客户端绑定到服务后,这个方法会被回调IBinder service
      
* 会把binder对象返回给客户端.
    
  */
  
   public void onServiceConnected(ComponentName name, IBinder service) {
 
  iStundent = (IStundent)service;
   
//将返回的binder对象转换为实现了IStudent接口的对象.IStudent
 
 }
  
public void onServiceDisconnected(ComponentName name) {
 
  //当客户端不和服务绑定的时候
  
 iStundent = null;
  
}
    }
 
   //当服务被摧毁的时候自动用unbindService,解除和服务的绑定.
 
   @Override
 
protected void onDestroy() {

  unbindService(conn);
 
 super.onDestroy();
 
}

 
private final class ButtonClickListener implements View.OnClickListener{
 
 public void onClick(View v) {
  
 String no = studentno.getText().toString();
 
  //得到用户输入的学号
  
 String name = iStundent.queryStudent(Integer.valueOf(no));

   //得到学号对应的学生姓名
  
 resultView.setText(name);
  
}
    }
}
-----------------------------------------------------------------------------
4./studentquery/src/com/credream/stuquery/StudentService.java
  package com.credream.stuquery;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
/**
 * 这个是服务类
 * @author xiaofeng
 *
 */

public class StudentService extends Service{
 private String[] names = {"李德伟","李小龙","李连杰"};
 private IBinder binder = new StundentBinder();
 
 public String query(int no){
  if(no>0 && no<4){
   return names[no - 1];
  }
  return null;
 }
 //提供这个方法可以让访问者访问服务
 @Override
 public IBinder onBind(Intent intent) {
  return binder;
 }
 /**
  * Binder这个类,已经实现了IBinder这个接口.
  * StundentBinder这个类继承Binder就可以实现IBinder接口了.
  * 可以看到这个类是私有的那么,客户端是无法直接调用它的,那么这个是用一根接口实现对这个类的调用.
  * @author xiaofeng
  *这个类用的很巧妙.
  *实现接口后IStudent
  *当客户端和服务连接好以后,当返回binder对象的时候,会调用这里面的queryStudent方法
  */
 private class StundentBinder extends Binder implements IStundent{
  public String queryStudent(int no) {
   return query(no);//这里就是通过服务中的query方法,来实现在不
  }
 }

}
-------------------------------------------------------------------------------------
5./studentquery/AndroidManifest.xml
  <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.credream.stuquery"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".StudentqueryActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  <!-- 配置服务,这样只能使用显示激活服务 -->      
            <service android:name=".StudentService"/>
  
    </application>

</manifest>

内容概要:本文档详细介绍了基于Google Earth Engine (GEE) 构建的阿比让绿地分析仪表盘的设计实现。首先,定义了研究区域的几何图形并将其可视化。接着,通过云掩膜函数裁剪操作预处理Sentinel-2遥感影像,筛选出高质量的数据用于后续分析。然后,计算中值图像并提取NDVI(归一化差异植被指数),进而识别绿地及其面积。此外,还实现了多个高级分析功能,如多年变化趋势分析、人口-绿地交叉分析、城市热岛效应分析、生物多样性评估、交通可达性分析、城市扩张分析以及自动生成优化建议等。最后,提供了数据导出、移动端适配报告生成功能,确保系统的实用性便捷性。 适合人群:具备一定地理信息系统(GIS)遥感基础知识的专业人士,如城市规划师、环境科学家、生态学家等。 使用场景及目标:①评估城市绿地分布及其变化趋势;②分析绿地人口的关系,为城市规划提供依据;③研究城市热岛效应及生物多样性,支持环境保护决策;④评估交通可达性,优化城市交通网络;⑤监测城市扩张情况,辅助土地利用管理。 其他说明:该系统不仅提供了丰富的可视化工具,还集成了多种空间分析方法,能够帮助用户深入理解城市绿地的空间特征及其对环境社会的影响。同时,系统支持移动端适配,方便随时随地进行分析。用户可以根据实际需求选择不同的分析模块,生成定制化的报告,为城市管理提供科学依据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值