service 总结
来源:互联网 发布:办公软件培训课件 编辑:程序博客网 时间:2024/06/05 19:29
最近一直在学习service ,刚开始的时候以为service跟activity一样,很简单,
但后来学习中发现里面好多东西自己都看不懂,真是不知道该从哪里开始做起了
现在好好理一下:
首先在做关于service的简单实用时摘抄了别人的一个例子,里面,没有牵涉到 bind绑定
但下一个如果要绑定activity的话继承service的类就要继承一个接口,还要实现一个内部类且该类也要继承该接口
这是为什么呢!我没有实现接口的定义 ServiceConnection这个接口两个函数当建立连接时别调用,当失去连接时被调用!它有什么作用,我每次失败时该函数都不被调用,用startservice就可以,用bindservice就出错!
那把serviceconnection里面的内容给注释掉,成功运行,
结合dmms 说明 service2 s2 = ((service2.MyBinder)service).getService();出错切实类型强制转换出错 应该是内部类myBinder出错它又继承了Binder类,关键是这个内部类是用来干什么的?我们看一下 Binder这个类!他其实就是两个进程数据的中转站,这里也就是activity与service的中转站(客户端和服务器)。他把activity请求的东西转给service后。。。。。当然内部太复杂,不想管了,上面那就代码应该是想通过继承Binder来返回从service获得的信息。但中间cast出错!反正这个程序没有用到返回的数据,我先不管了!
看一下别人关于service的总结的程序
学习android有一段时间了,感觉学到的东西似乎很有限,归根结底就是自己动手写的程序太少了。我觉得学习编程,光停留在“看“是不行了,看了10成感觉似乎也就能记得一两成,等碰到问题的时候又要回去查看。所以必须通过动手来学习,在动手的过程中会碰到很多看的时候根本不会发现的问题,带着问题去看去解决问题才会得到很大的提高。在我做这个练习的过程中碰到多很多问题,我会在下面对应的位置将问题给总结上。
首先说一下程序的主要结构。有一个主界面Activity,通过主界面可以打开三个副界面Activity,每个副界面对应一个Service类,代表了一种使用Service的方法,其具体包括:
1.简单的启动Service;
2.通过bind使用Service;
3.使用AIDL实现进程间的通信。
先看一下Manifest.xml文件吧。在这里面声明了3个Activity和3个Service。在这里遇到的问题主要是出来的界面左右各空了一块,没有占据整个屏幕。查找原因是少了最后的那句 <uses-sdk android:minSdkVersion="7"/>,其原因估计默认的版本比较小,不能很好地适应我的模拟器。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".start" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".dirstart">
</activity>
<activity android:name=".bindStart">
</activity>
<activity android:name=".remoteStart">
</activity>
<service android:enabled="true" android:name=".dirtStartService">
<intent-filter>
<action android:name="com.test.dirStartService"></action>
</intent-filter>
</service>
<service android:enabled="true" android:name=".bindService">
<intent-filter>
<action android:name="com.test.bindService"></action>
</intent-filter>
</service>
<service android:enabled="true" android:name=".remoteService">
<intent-filter>
<action android:name="com.test.remoteService"></action>
</intent-filter>
</service>
</application>
<uses-sdk android:minSdkVersion="7"/>
</manifest>
下面是主界面的代码,我将其命名为start.java。这里没有什么特别之处,只是在一个Activiy中添加了3个按钮,为每个按钮都添加了事件响应行为,启动各个副界面。
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
publicclassstartextendsActivityimplements OnClickListener{
privateString TAG="servicetest";
privateButton dirtstart;
privateButton bindstart;
privateButton remotestart;
/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dirtstart=(Button)findViewById(R.id.dirtstart);
bindstart=(Button)findViewById(R.id.bindstart);
remotestart=(Button)findViewById(R.id.remtstart);
addListener();
}
/*
* 添加对按钮的监听
*/
privatevoid addListener(){
dirtstart.setOnClickListener(this);
bindstart.setOnClickListener(this);
remotestart.setOnClickListener(this);
}
@Override
publicvoid onClick(View v){
switch(v.getId()){
//以直接启动的方式启动服务
case R.id.dirtstart:
Toast.makeText(this.getApplicationContext(),"dirstart", Toast.LENGTH_SHORT).show();
Log.d(TAG,"dirstart");
Intent intent=new Intent(this,dirstart.class);
startActivity(intent);
break;
//以bind的方式启动服务,并同服务进行交互
case R.id.bindstart:
Toast.makeText(this.getApplicationContext(),"bindstart", Toast.LENGTH_SHORT).show();
Log.d(TAG,"bindstart");
Intent intent1=new Intent(this,bindStart.class);
startActivity(intent1);
break;
//以AIDL实现进程间的通信
case R.id.remtstart:
Toast.makeText(getApplicationContext(),"remtstart", Toast.LENGTH_SHORT).show();
Log.d(TAG,"remotestart"); Intent intent2=new Intent(this,remoteStart.class);
startActivity(intent2);
break;
}
}
}
主界面的显示如下图所示:
下面说一下各个副界面的实现。
在点击了“直接启动Service”按钮后,触发事件启动第一个副界面,该界面使用的布局文件为/layout/dir.xml,如下所以。可以看到在这里我们不单纯地使用按钮了,而是使用了下拉菜单的形式,具体的实现我参考了SDK中Spinner的实现。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="直接控制服务"
android:gravity="center" android:id="@+id/textView1"
android:layout_width="fill_parent" android:layout_height="wrap_content"></TextView>
<Spinner
android:id="@+id/spinr"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:drawSelectorOnTop ="true"
android:prompt="@string/select"
>
</Spinner>
<TextView android:id="@+id/textview"
android:gravity="center"
android:layout_width="fill_parent" android:layout_height="wrap_content"></TextView>
</LinearLayout>
对于该界面起名为dirstart.java,代码如下。在这里面使用了一个SpinnerAdapter来装载Spinner所要显示的内容,当然对于内容的定义是在value.xml中进行定义的,这个会在后面贴上。
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;
publicclass dirstart extendsActivity{
SpinnerAdapter mAdapter;
Spinner spinner;
TextView textview;
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.dir);
textview=(TextView)findViewById(R.id.textview);
spinner=(Spinner)findViewById(R.id.spinr);
//获取内容
this.mAdapter=ArrayAdapter.createFromResource(this.getApplicationContext(), R.array.actions,
android.R.layout.simple_spinner_dropdown_item);
//添加spinner所要显示的内容
spinner.setAdapter(mAdapter);
//给spinner添加监听器
OnItemSelectedListener spinnerListener =new myOnItemSelectedListener(this,this.mAdapter);
spinner.setOnItemSelectedListener(spinnerListener);
}
//停止服务并结束本ACTIVITY
publicvoidstop(){
Intent intent=new Intent("com.test.dirStartService");
stopService(intent);
this.finish();
}
class myOnItemSelectedListener implements OnItemSelectedListener{
public myOnItemSelectedListener(dirstart dirstart, SpinnerAdapter mAdapter){
// TODO Auto-generated constructor stub
}
@Override
publicvoid onItemSelected(AdapterView<?>parent,Viewview,intposition,longid){
int act=0;
switch(Integer.parseInt(String.valueOf((id)))){
case 0:
textview.setText("啥也不做");
// Toast.makeText(getApplicationContext(), "啥也不做", Toast.LENGTH_LONG).show();
break;
case 1:
act=1;
textview.setText("服务已启动");
// Toast.makeText(getApplicationContext(), "启动服务", Toast.LENGTH_LONG).show();
start(act);
break;
case 2:
act=2;
textview.setText("服务已结束");
// Toast.makeText(getApplicationContext(), "结束服务", Toast.LENGTH_LONG).show();
start(act);
break;
case 3:
stop();
break;
}
}
/*
* 启动服务
*/
privatevoidstart(int act){
Intent intent=new Intent("com.test.dirStartService");
Bundle bundle=new Bundle();
//给要启动的服务传递参数
bundle.putInt("act", act);
intent.putExtras(bundle);
Log.v("start","startservice");
startService(intent);
}
@Override
publicvoid onNothingSelected(AdapterView<?>parent){
// TODO Auto-generated method stub
}
}
}
可以看到上面只是一个Activty,只是同用户交互的窗口,服务的实现还要在另外的一个类dirStartService.java中实现。下面是服务的代码。在服务的代码中,通过一个线程来操作一个变量,每一秒钟使变量的值加一,并在logcat中打印出来。这里碰到的问题就是线程的启动方面,因为在程序中只使用了一个线程,如果服务在暂停后又开启服务的话就会发生错误,因为前面的线程已经执行完了。所以在每次启动线程前要判断线程的状态,如果前面有线程执行过,就需要重新建立一下线程的对象。
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
publicclass dirtStartService extends Service {
privatestaticfinalString TAG="dirService";
privateint n=0;
//用来计数的线程
privatecountthread;
@Override
public IBinder onBind(Intent intent){
returnnull;
}
publicvoid onCreate(){
super.onCreate();
Log.d(TAG,"oncreate");
thread=newcount();
}
publicvoid onStart(Intent intent,int startId){
Log.d(TAG,"onstart");
if(intent!=null){
//获取传送来的参数,并根据参数进行对应的操作
Bundle bundle=intent.getExtras();
int act=bundle.getInt("act");
Log.d(TAG,"act is:"+act);
switch(act){
case 1:
start();
break;
case 2:
stop();
break;
}
}
}
/*
* 线程类
*/
classcountextendsThread{
//控制线程的结束
privateboolean pause=false;
publicvoid setPause(boolean tof){
pause=tof;
}
publicboolean getPauseStatues(){
return pause;
}
publicvoidrun(){
while(!pause){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
//每隔一秒钟输出加一后的值
n++;
Log.d(TAG,"n is:"+n);
}
}
}
/*
* 结束线程的执行
*/
privatevoidstop(){
thread.setPause(true);
}
/*
* 重新启动线程
*/
privatevoidstart(){
//如果前面有线程在执行,则重新启动线程
if(thread.getPauseStatues()==true){
thread=newcount();
thread.setPause(false);
}
thread.start();
Log.d(TAG,String.valueOf(thread.getPauseStatues()));
}
}
该界面的效果如下图所示:
当点击该Spinner后,弹出提前设定好的选项,单击某一项进行操作。
启动服务后的输出结果如下图所示:
将所有的东西都放在一篇文章中显得太多,下篇文章介绍另外两种方式的实现。
继续接上文。点击主界面上的“bind启动Service”后,进入第二个副界面。第二个副界面我使用ListView来实现和用户的交互,并且能实时获取服务中提供的数值将其显示在界面上。该界面的布局文件为bind.xml其内容如下:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout android:id="@+id/RelativeLayout02"
android:paddingTop="21.0px"
android:paddingBottom="10.0px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15.0px"
android:layout_marginTop="62.0px"
android:layout_marginRight="15.0px">
<ListView android:id="@+id/listView1"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
</ListView>
<TextView android:id="@+id/bindtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/listView1"
android:gravity="center"
/>
</RelativeLayout>
</LinearLayout>
在这里我使用了RelativeLayout布局,因为如果还用LinerLayout布局的话就不能正常显示TextView了。界面的类我命名为bindStart.java,在这里碰到了难题,就是如何更新显示的内容。我的想法就是使用一个线程,每一秒中从Service那里获取数字并显示出来。但是系统却频频报错。向别人提问后才知道对于Activity界面的更新只有主线程才可以,别的线程一律不允许碰。那么要告诉主线程更新显示怎么办呢?这就要用到Handler类,Handler类可以说是用来实现线程间的通信。通过一个线程获取数据并发信息给主线程,主线程收到信息后按要求更新显示的内容。类的内容为:
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
publicclass bindStart extendsActivity{
privatefinalstaticString TAG="bindStart";
ListViewlistView;
TextView textView;
ArrayAdapter adapter;
bindService bindservice;
int num;
int act;
//更新显示用的线程
fresh freshtext;
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.bind);
listView=(ListView)findViewById(R.id.listView1);
textView =(TextView)findViewById(R.id.bindtext);
textView.setText(num+"");
//设定list的背景色,否则显示不出来
int mycolor=getResources().getColor(R.color.bachgroud);
listView.setBackgroundColor(mycolor);
//获得显示的内容
adapter=ArrayAdapter.createFromResource(this.getApplicationContext(), R.array.actions,
android.R.layout.simple_spinner_dropdown_item);
listView.setAdapter(adapter);
freshtext=new fresh();
//开始bind
Log.d(TAG,"connecting.....");
Intent intent =new Intent("com.test.bindService");
bindService(intent, sc,Context.BIND_AUTO_CREATE);
//对list添加点击事件响应
listView.setOnItemClickListener(new OnItemClickListener(){
@Override
publicvoid onItemClick(AdapterView<?>parent,Viewview,intposition,longid){
switch(position){
case 0:
Toast.makeText(getApplicationContext(),"啥也不做", Toast.LENGTH_SHORT).show();
break;
case 1:
act=1;
start(act);
Toast.makeText(getApplicationContext(),"启动服务", Toast.LENGTH_SHORT).show();
break;
case 2:
act=2;
start(act);
Toast.makeText(getApplicationContext(),"暂停服务", Toast.LENGTH_SHORT).show();
break;
case 3: act=3; start(act);
stop();
break;
}
}
});
}
privatevoidstart(int act){
Intent intent=new Intent("com.test.bindService");
Bundle bundle=new Bundle();
bundle.putInt("act", act);
intent.putExtras(bundle);
startService(intent);
Log.v("start","startbindservice");
//如果当前有更新线程在运行,首先结束它
if(freshtext.running){
freshtext.running=false;
}
//重新启动更新线程
freshtext=new fresh();
freshtext.running=true;
newThread(freshtext).start();
}
publicvoidstop(){
if(freshtext.running){
freshtext.running=false;
}
this.unbindService(sc);
this.finish();
}
class fresh implementsRunnable{
Boolean running=false;
@Override
publicvoidrun(){
while(running){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
//获取服务中产生的数字
num =bindservice.get();
//通过handler发消息给主线程,更新显示的内容
Message msg=new Message();
msg.what=1;
h.sendMessage(msg);
Log.d(TAG,"num is :"+num);
}
}
}
ServiceConnection sc=new ServiceConnection(){
@Override
publicvoid onServiceConnected(ComponentName name, IBinder service){
bindservice=((bindService.myBinder)service).getService();
Log.d(TAG,"in onServiceConnected");
}
@Override
publicvoid onServiceDisconnected(ComponentName name){
bindservice=null;
}
};
/*
* 主线程处理收到的信息
*/
Handler h=newHandler(){
publicvoid handleMessage(Message msg){
Log.d(TAG,"msg is "+msg.toString());
switch(msg.what){
case 1:
textView.setText(num+"");
break;
}
}
};
}
接下来当然是服务类了,没有什么特别之处,还是每秒钟对变量加一。
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
publicclass bindService extends Service {
privatefinalstaticString TAG="bindService";
private IBinder binder=new myBinder();
privateint n=0;
privatecountthread;
@Override
public IBinder onBind(Intent intent){
// TODO Auto-generated method stub
return binder;
}
publicclass myBinder extends Binder{
public bindService getService(){
return bindService.this;
}
}
publicintget(){
return n;
}
publicvoid onCreate(){
super.onCreate();
Log.d(TAG,"onCreate");
thread=newcount();
}
publicvoid onStart(Intent intent,int startId){
Log.d(TAG,"onstart");
if(intent!=null){
Bundle budle=intent.getExtras();
int act=budle.getInt("act");
switch(act){
case 1:
start();
break;
case 2:
stop();
break;
case 3:
finsish();
}
}
}
private void finsish() {
thread.setPause(true);
stopSelf();
}
classcountextendsThread{
privateboolean pause=false;
publicvoid setPause(boolean tof){
pause=tof;
}
publicboolean getPauseStatues(){
return pause;
}
publicvoidrun(){
while(!pause){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
n++;
Log.d(TAG,"n is:"+n);
}
}
}
privatevoidstop(){
thread.setPause(true);
}
privatevoidstart(){
stop();
if(thread.getPauseStatues()==true){
thread=newcount();
thread.setPause(false);
}
thread.start();
Log.d(TAG,String.valueOf(thread.getPauseStatues()));
}
}
该界面的显示如下图所示:最下面的数字每秒钟会更新一次。
最后就是远程Service了,使用了AIDL接口实现Activity和Service之间的通信,在这个界面中我使用单选按钮来和用户就行交互。布局文件为remote.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<RadioButton
android:layout_width="wrap_content"
android:id="@+id/radio0"
android:layout_height="wrap_content"
android:text="@string/do_nothing"
android:checked="true">
</RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:id="@+id/radio1"
android:layout_height="wrap_content"
android:text="@string/start">
</RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:id="@+id/radio2"
android:layout_height="wrap_content"
android:text="@string/pause">
</RadioButton>
<RadioButton
android:layout_width="wrap_content"
android:id="@+id/radio3"
android:layout_height="wrap_content"
android:text="@string/stop">
</RadioButton>
</RadioGroup>
<TextView
android:id="@+id/radioText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
</TextView>
</LinearLayout>
既然使用到了AIDL当然要创建AIDL文件了,AIDL文件命名为IremoteService.aidl
void stop();}
下面是界面的代码,在里面同样通过一个线程发消息给主线程,实时更新显示的内容,这次显示的内容为系统时间,由Service端负责获取时间,文件命名为remoteStart.java
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
publicclass remoteStart extendsActivity{
privateString TAG="remoteStart";
private RadioGroup radiogroup;
private RadioButton donothing;
private RadioButton start;
private RadioButton pause;
private RadioButton stop;
private TextView text;
privatebooleanstatus=true;
private IremoteService remoteservice;
privateStringtime;
private getTimeThread gettimethread;
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.remote);
radiogroup=(RadioGroup)findViewById(R.id.radioGroup1);
donothing=(RadioButton)findViewById(R.id.radio0);
start=(RadioButton)findViewById(R.id.radio1);
pause=(RadioButton)findViewById(R.id.radio2);
stop=(RadioButton)findViewById(R.id.radio3);
text=(TextView)findViewById(R.id.radioText);
//初始化更新时间的线程
gettimethread=new getTimeThread();
radiogroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
@Override
publicvoid onCheckedChanged(RadioGroup group,int checkedId){
if(start.getId()==checkedId){
if(!status){
//如果点击过暂停服务,则重新启动更新时间线程
gettimethread=new getTimeThread();
status=true;
}
newThread(gettimethread).start();
Toast.makeText(getApplicationContext(),"启动服务", Toast.LENGTH_SHORT).show();
}
elseif(pause.getId()==checkedId){
status=false;
Toast.makeText(getApplicationContext(),"暂停服务", Toast.LENGTH_SHORT).show();
}
elseif(stop.getId()==checkedId){
stopactivity();
Toast.makeText(getApplicationContext(),"停止服务", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),"啥也不做", Toast.LENGTH_SHORT).show();
}
}
});
Log.d(TAG,"connecting");
Intent intent=new Intent("com.test.remoteService");
bindService(intent,sc,Context.BIND_AUTO_CREATE);
}
/*
* 该线程负责从服务端获取时间,并更新显示
*/
class getTimeThread implementsRunnable{
publicvoidrun(){
while(status){
try{
time=remoteservice.getTime();
Log.d(TAG,time);
}catch(RemoteException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg=new Message();
msg.what=1;
h.sendMessage(msg);
try{
//每秒更新一次
Thread.sleep(1000);
}catch(InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
/*
* 负责接受信息,并根据信息更新显示的时间
*/
Handler h=newHandler(){
publicvoid handleMessage(Message msg){
Log.d(TAG,"msg is "+msg.toString());
switch(msg.what){
case 1:
//更新显示
text.setText(time);
break;
}
}
};
/*
* 停止服务,并终止
*/
publicvoid stopactivity(){
try{
status=false;
this.unbindService(sc);
remoteservice.stop();
this.finish();
}catch(RemoteException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ServiceConnection sc=new ServiceConnection(){
@Override
publicvoid onServiceConnected(ComponentName name, IBinder service){
remoteservice=IremoteService.Stub.asInterface(service);
}
@Override
publicvoid onServiceDisconnected(ComponentName name){
remoteservice=null;
}
};
}
在服务端,相对来说比较简单只是获取系统的时间而已,类命名为remoteService.java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
importjava.text.SimpleDateFormat;
importjava.util.Date;
publicclass remoteService extends Service {
privateString TAG="remoteService";
privateStringtime;
//设置时间格式
privateSimpleDateFormatformat=newSimpleDateFormat("yyyy MMM d EEE HH:mm:ss");
private IremoteService.Stub binder=new IremoteService.Stub(){
@Override
publicStringgetTime()throwsRemoteException{
Log.d(TAG,"gettime");
//获取系统时间
time=format.format((newDate()));
returntime;
}
@Override
publicvoidstop()throwsRemoteException{
Log.d(TAG,"stop");
stopSelf();
}
};
@Override
public IBinder onBind(Intent intent){
// TODO Auto-generated method stub
return binder;
}
publicvoid onCreate(){
super.onCreate();
Log.d(TAG,"oncreate");
}
}
现在就可以了,界面如下图所示,显示的时间会每秒更新一次。
此外,系统想要顺利运行似乎还缺了几个文件,分别为value目录下的strings.xml和color.xml,下面是strings.xml。
<resources>
<string name="hello">请选择</string>
<string name="app_name">Service练习</string>
<string name="dirct_start">直接启动service</string>
<string name="bind_start">bind启动service</string>
<string name="remote_start">远程启动service</string>
<string name="do_nothing">啥也不做</string>
<string name="start">启动服务</string>
<string name="pause">暂停服务</string>
<string name="stop">停止服务</string>
<string-array name="actions">
<item>啥也不做</item>
<item>启动服务</item>
<item>暂停服务</item>
<item>停止服务</item>
</string-array>
<string name="select">选择一个操作</string>
</resources>
下面为color.xml
<resources>
<color name="bachgroud">#7fffffff</color>
<color name="textback">#77777777</color>
</resources>
至此,我这个系统终于大功告成了。
- service 总结
- Service总结
- Service总结
- service总结
- Service总结
- Service总结
- Service总结
- service总结
- Service总结
- Service总结
- Service总结
- Service总结
- service总结
- service总结
- web Service开发总结
- Java Message Service 总结
- web service 学习总结
- Android Service全面总结
- JSON 序列化和反序列化——JavaScriptSerializer实现
- DELPHI 2010 的泛型 还是很给力的
- checkbox、radio JQuery操作
- DW-BI Tool
- Linq To Sql的总结
- service 总结
- wifi连接流程分析
- strConv vbUnicode vb6 to vb.net
- 什么是REST架构
- 查询手机所在地理位置的简单方法
- StrConv vbFromUnicode vb6 to vb.net
- Ready, Set, Go - Getting started with Tuscany
- PHP测试程序的运行时间
- DatePickerDialog 的应用