您的位置:首页 > 产品设计 > UI/UE

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

2014-07-19 20:56 591 查看
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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐