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

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>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值