使用绑定服务并且与Activity通信进行UI更新的两种方法

BindService中使用bindService()方法来绑定服务,调用者和绑定者绑在一起,调用者一旦退出服务也就终止了。

生命周期【onCreate()->onBind()->onUnbind()->onDestroy()】

由于Android 中的Service使用了onBind 的方法去绑定服务,返回一个Ibinder对象进行操作,而我们要获取具体的Service方法的内容的时候,我们需要Ibinder对象返回具体的Service对象才能操作,所以说具体的Service对象必须首先实现Binder对象,这个样子的话我们才能利用bindService的方法对Service进行绑定,获取Binder对象之后获取具体的Service对象,然后才获取Service中的方法等等。所以我们需要注意的是bindService的方式去绑定服务获取的必定是实现了Binder的对象,所以这是我们必须使用Binder的方式去获取Service的方式而不是直接使用Service的类,这个是Android内部实现所约束的。

绑定的过程函数调用的顺序是这样的:

Intent intent = new Intent(MainActivity.this,BindService.class) ->新建了BindService对象->新建了MyBinder对象->bindService(intent, conn, Context.BIND_AUTO_CREATE)->系统回调oncteate()和onBind()->onBind()函数返回MyBinder对象->传递MyBinder对象到onServiceConnected()-> 通过传递的Binder对象获取刚刚和Binder对象对应的BindService 对象 ->调用Service中定义的方法。

有时在Activity函数中想要循环更新UI界面,需要开启一个线程,在线程中更新界面,但又有一个问题是线程中许多控件不能更新(ProsessBar除外),说以需要用到Handler对象,将更新界面的语句写在runnable中,用Handler对象的post方法发送到消息队列中。这是服务于Activity通信的方法之一,但是比较被动。

另一种是使用回调的方法,主动提示Activity更新界面。

现将代码全部写出

Main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.lightcontroldemo.MainActivity"
    tools:ignore="MergeRootFrame" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="被动查询"
        android:textSize="@dimen/abc_action_bar_progress_bar_size" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="@dimen/abc_action_bar_progress_bar_size"
        android:gravity="center_horizontal"
        android:text="主动通知" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="bind"
        android:text="显示时间" />

</LinearLayout>

MainActivity.java

package com.example.lightcontroldemo;

import java.text.SimpleDateFormat;
import java.util.Date;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.annotation.SuppressLint;
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.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Build;

public class MainActivity extends ActionBarActivity {
	
	private LightService myService;
	private TextView tt;
	private TextView tt2;
	private Handler myHandler;
	private static Date dd;
	private Runnable run=new Runnable(){

		@SuppressLint("SimpleDateFormat")
		@Override
		public void run() {
//			// TODO Auto-generated method stub
			SimpleDateFormat sdf=new SimpleDateFormat("hh:mm:ss");
			tt.setText(sdf.format(dd));
			
			

		}
		
	};
	private Runnable run2=new Runnable(){

		@SuppressLint("SimpleDateFormat")
		@Override
		public void run() {
//			// TODO Auto-generated method stub
			SimpleDateFormat sdf=new SimpleDateFormat("hh:mm:ss");
			tt2.setText(sdf.format(dd));
			
			

		}
		
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tt=(TextView)findViewById(R.id.textView1);
		tt2=(TextView)findViewById(R.id.textView2);
		myHandler=new Handler();
		Intent i=new Intent(MainActivity.this,LightService.class);
		bindService(i, conn, Context.BIND_AUTO_CREATE);
		
		
//		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	public void bind(View v){
		

			if(myService==null)
				Toast.makeText(MainActivity.this, "null", Toast.LENGTH_SHORT).show();

			else 
				{

				Thread the=new Thread(){
					public void run() {  
						while(true){
						dd=myService.getDate();
						myHandler.post(run);
						try {
                            sleep(1000);                            //直接调用
                          } catch (InterruptedException e) {
                            return;
                          }
						}
					}
				};
				the.start();
				
				
		}

	}
	

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	private ServiceConnection conn=new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			myService=((LightService.myBinder)service).getService();
			myService.SetOnTextViewListener(new TextViewListener() {
					
					@Override
					public void onTextView(Date d) {
						MainActivity.dd=d;
						myHandler.post(run2);
						
					}
				});	
		}
	};
}

LightService.java

package com.example.lightcontroldemo;

import java.util.Date;

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


public class LightService extends Service {
private Handler myHandler;
private Date d;
private TextViewListener textviewlistener;
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		myHandler=new Handler();
		d=new Date();
		
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d("SER", "SoundDetectService on Bind...");
//		myHandler.postDelayed(r, 1000);
		Thread th=new Thread(null,r,"r");
		th.start();

		return new myBinder() ;
	}
	
	private Runnable r=new Runnable(){

		@Override
		public void run() {
			while(true)
			{
				d=new Date();
				try {
                  Thread.sleep(1000);                            //直接调用
                } catch (InterruptedException e) {
                  return;
                }
				if(textviewlistener!=null)
				textviewlistener.onTextView(d);
				
			}
			

		}
		
	};
	public Date getDate(){
		return d;
	}
	public void SetOnTextViewListener(TextViewListener textviewlistener){
		this.textviewlistener=textviewlistener;
	}
	public class myBinder extends Binder{
			public LightService getService(){
		
					return LightService.this;
		
				}
			}
}

TextViewListener.java

package com.example.lightcontroldemo;

import java.util.Date;

public interface TextViewListener {
public void onTextView(Date d);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值