Service和Activity的通信以及Handler和AsyncTask

Service做为Android四大组件之一,才疏学浅的我在近期对它有了点粗鄙的认识,真诚的我就迫不及待地想让大家了解俺对Service的理解,有错误的地方还请大家多多指教。。。

Service它是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序。平时我们手机上很多应用都在后台执行。这也是service重要的原因,除此之外,它也是用来执行需要执行长时间的任务。因为我们知道android是单线程,如果在主线程中跑较长时间任务的话会堵塞主线程。所以我们有时候还需要主线程和Activity之间的通信。

基本的Service用法我就不详细介绍了,先看图解:

Service和Activity的通信以及Handler和AsyncTask_第1张图片

下面我们通过在service端实现比较两个数大小的功能,在主线程显示更大的数。

MyBinderService

package com.example.lab4exam03;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MyBinderService extends Service{

	int num1;
	int num2;
	
	
	public MyBinderService(){
		 
	 }

	//先创建Service,且只会执行一次
	@Override
	public void onCreate() {
		
		super.onCreate();
		
		
	}
	//销毁Service
	@Override
	public void onDestroy() {
		
		super.onDestroy();
	}
	//执行Service,会执行很多次
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		
		
		
		return super.onStartCommand(intent, flags, startId);
	}
	
	//接触绑定,因为我们除了通过StartService可以开启Service还可以通过绑定自动创建
	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}
	//必须实现的方法,也是最重要的的方法
	@Override
	public IBinder onBind(Intent intent) {//IBinder是一个接口,而Binder实现了这个接口
		return new MyBinder();
		
	}
	
	public class MyBinder extends Binder{
		
		public int IntCompare(){//比较,返回较大值
			return (num1 >= num2 ? num1 : num2);
		}
		public void  setData(int num1, int num2){//将Activity里的数据通过IBinder传到Service
			MyBinderService.this.num1 = num1;
			MyBinderService.this.num2 = num2;
			
		}
		
	}
	

}

采用AsynvTask的MainActivity



package com.example.lab4exam03;

import com.example.lab4exam03.MyBinderService.MyBinder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
	TextView tv;
	Button bt;
	Intent intent;
	Handler handler;
	EditText ed1;
	EditText ed2;
	MyBinder binder;
	int num1,num2;
	//为绑定服务的参数
	ServiceConnection conn = new ServiceConnection(){
		//最精华的部分,就是把安插在Service里的间谍iBinder找过来获取或者传递数据
		@Override
		public void onServiceConnected(ComponentName arg0, IBinder iBinder) {
			binder = (MyBinder) iBinder;
			
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			// TODO Auto-generated method stub
			
		}
		
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//获取控件
		ed1 = (EditText)findViewById(R.id.editText1);
		ed2 = (EditText)findViewById(R.id.editText2);
		tv = (TextView) this.findViewById(R.id.textView3);
		bt = (Button) this.findViewById(R.id.button1);
		
		intent = new Intent(this,MyBinderService.class);
		
	
		//绑定服务,这里的Intent和onstartCommand参数里的intent是同一个,所以我们也能通过这种方式
		//向Service传递数据
		this.bindService(intent, conn, BIND_AUTO_CREATE);
		num1 = Integer.parseInt(ed1.getText().toString());
		num2 = Integer.parseInt(ed2.getText().toString());
		
	}
	/*
	 * 异步类的三个参数
	 * 第一个表示执行doInBackground方法传进来的参数类型
	 * 第二个是进度值的类型
	 * 第三个是执行完任务返回的类型,也就是onPostExecute的参数类型
	 */
	class MyAsynvTask extends AsyncTask{
		
		//执行一些任务前的UI操作
		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
		}
		
		@Override
		protected void onPostExecute(Integer i) {//UI操作,将textview的内容设置成最大值
			tv.setText(i);
			
		}

		@Override
		protected Integer doInBackground(Integer... num) {//返回最大值到onPostExecute()
			binder.setData(num[0], num[1]);
			return binder.IntCompare();
		}
		
		
	}
	
	public void click(View view){
		new MyAsynvTask().execute(num1,num2);//启动异步,类似thread.start()方法,
		
	}
}

 

采用Handler的MainActivity



package com.example.lab4exam01;

import com.example.lab4exam01.MyBinderService.MyBinder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
	TextView tv;
	Button bt;
	Intent intent;
	Handler handler;
	EditText ed1;
	EditText ed2;
	MyBinder binder;
	ServiceConnection conn = new ServiceConnection(){

		@Override
		public void onServiceConnected(ComponentName arg0, IBinder iBinder) {
			binder = (MyBinder) iBinder;
			
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			// TODO Auto-generated method stub
			
		}
		
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ed1 = (EditText)findViewById(R.id.editText1);
		ed2 = (EditText)findViewById(R.id.editText2);
		tv = (TextView) this.findViewById(R.id.textView3);
		bt = (Button) this.findViewById(R.id.button1);
		intent = new Intent(this,MyBinderService.class);
		handler = new Handler();
		
		

		//启动服务
		this.bindService(intent, conn, BIND_AUTO_CREATE);
		//startService(intent);
	}
	
	
	
		
	Thread thread = new Thread(new Runnable(){

		@Override
		public void run() {
			if(binder != null) {
			int num1 = Integer.parseInt(ed1.getText().toString());
			int num2 = Integer.parseInt(ed2.getText().toString());
			binder.setData(num1, num2);
		}
			tv.setText("较大的数为:"+binder.IntCompare());
			
		}
		
	});
	
	public void click(View view){
		handler.post(thread);
		
	}
}

activity_main.XML



    

        

        

            
        

    

    

        

        

    

    

        

AndroidManifest.xml




    

    
        
            
                

                
            
        
        
        
    


但是假如我们不通过绑定服务来启动service,而是通过startService方法的话,我们就无法获得Ibinder对象,也就无法通过Ibinder对象进行Service和Activity之间的通信。所有我们换一种方式

1.Activity-------(Intent)------->Service

2.Service------(Broadcast)------->Activity

MyBinderService

package com.example.lab4exam02;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyBinderService extends Service{
	
	String num1;
	String num2;
	
	
	public MyBinderService(){
		 
	 }

	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		
		super.onDestroy();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		num1 = intent.getStringExtra("num1");
		num2 = intent.getStringExtra("num2");
		
		Log.d("tag","1");
		//新建intent发送广播
		if((num1 == null || num2 == null)||(num1.trim().length() <= 0 || num2.trim().length() <= 0)){
		//如果文本框无内容就不是发送广播
		}
		else{
			
			Intent intent1 = new Intent();//新建一个intent用来发送广播
			intent1.setAction("receiver");//设置广播的Action
			intent1.putExtra("result",  Intcompare());
			sendBroadcast(intent1);
		}
	
		return super.onStartCommand(intent, flags, startId);
	}
	public String Intcompare(){//比较方法
		
			return Integer.parseInt(num1) >= Integer.parseInt(num2) ? num1 : num2;
		
	}

	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}

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

	

}

MainActivity



package com.example.lab4exam02;


import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
	TextView tv;
	Button bt;
	Intent intent;
	Handler handler;
	EditText ed1;
	EditText ed2;
	String result;
	
	public class MyReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context arg0, Intent intent) {
			MainActivity.this.result = intent.getStringExtra("result");
			
		}
		
	}
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		ed1 = (EditText)findViewById(R.id.editText1);
		ed2 = (EditText)findViewById(R.id.editText2);
		tv = (TextView) this.findViewById(R.id.textView3);
		bt = (Button) this.findViewById(R.id.button1);
		handler = new Handler();
		
		
		
		
		
			
			
	       
	}
	
	Thread thread = new Thread(new Runnable(){

		@Override
		public void run() {
			tv.setText("最大值为"+result);//设置textview的值
			
		}
		
	});
	
	public void click(View view){
		//向intent里传数据
		intent = new Intent(MainActivity.this,MyBinderService.class);
		intent.putExtra("num1", ed1.getText().toString());
		intent.putExtra("num2", ed2.getText().toString());
		//必须在输入文本框内容之后再启动Service,我们也可以通过判断文本框是否为空来StartService
		startService(intent);
		handler.post(thread);	//调用线程
	}
}

AndroidManifest.xml静态加入广播接收器

 
            
                
                   
                
        

完美!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

你可能感兴趣的:(Service和Activity的通信以及Handler和AsyncTask)