Android组件间的相互调用

我们研究两个问题,
1、Service如何通过Broadcaster更改activity的一个TextView。
(研究这个问题,考虑到Service从服务器端获得消息之后,将msg返回给activity)

2、Activity如何通过Binder调用Service的一个方法。
(研究这个问题,考虑到与服务器端交互的动作,打包至Service,Activity只呈现界面,调用Service的方法)

结构图见如下:

效果图如下:

点击“start service”按钮,启动Service,然后更改Activity的UI。

点击“send msg to server”按钮调用Service的方法,显示NotificationBar

代码

Myservice的:

package com.bankcomm.test;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Binder;
import android.os.IBinder;

public class Myservice extends Service {
private NotificationManager notificationManager = null;
private final IBinder binder = new LocalBinder();

@Override
public void onCreate() {
sendMsgtoActivity("Service is oncreating.\n");
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
String msg = "Activity is sendding message to service,\n Service send msg to server!\n";
sendMsgtoActivity(msg);
return binder;
}
private void sendMsgtoActivity(String msg){
Intent intent = new Intent("com.android.Hou.msg");
intent.putExtra("msg", msg);
this.sendBroadcast(intent);

}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();

if (notificationManager!= null) {
notificationManager.cancel(0);
notificationManager= null;

}
}
private void showNotification(String msg) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 定义Notification的各种属性
Notification notification =new Notification(R.drawable.ic_launcher,
"A Message Coming!", System.currentTimeMillis());
//FLAG_AUTO_CANCEL 该通知能被状态栏的清除按钮给清除掉
//FLAG_NO_CLEAR 该通知不能被状态栏的清除按钮给清除掉
//FLAG_ONGOING_EVENT 通知放置在正在运行
//FLAG_INSISTENT 是否一直进行,比如音乐一直播放,知道用户响应
notification.flags |= Notification.FLAG_ONGOING_EVENT; // 将此通知放到通知栏的"Ongoing"即"正在运行"组中
notification.flags |= Notification.FLAG_NO_CLEAR; // 表明在点击了通知栏中的"清除通知"后,此通知不清除,经常与FLAG_ONGOING_EVENT一起使用
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
//DEFAULT_ALL 使用所有默认值,比如声音,震动,闪屏等等
//DEFAULT_LIGHTS 使用默认闪光提示
//DEFAULT_SOUNDS 使用默认提示声音
//DEFAULT_VIBRATE 使用默认手机震动,需加上<uses-permission android:name="android.permission.VIBRATE" />权限
notification.defaults = Notification.DEFAULT_LIGHTS;
//叠加效果常量
//notification.defaults=Notification.DEFAULT_LIGHTS|Notification.DEFAULT_SOUND;
notification.ledARGB = Color.BLUE;
notification.ledOnMS =5000; //闪光时间,毫秒

// 设置通知的事件消息
//Intent notificationIntent =new Intent(MainActivity.this, MainActivity.class); // 点击该通知后要跳转的Activity
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); // 加载类,如果直接通过类名,会在点击时重新加载页面,无法恢复最后页面状态。
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentItent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, "Message", "Message:" + msg, contentItent);

// 把Notification传递给NotificationManager
notificationManager.notify(0, notification);

}
/**
* 从activity获取信息
*/
public void receiverMsgtoActivity(String msg){
sendMsgtoActivity("\n receiverMsgtoActivity:"+msg);
}
public void sendMsgtoServer(String msg){
showNotification(msg);
}
public class LocalBinder extends Binder{
public Myservice getService(){
return Myservice.this;
}
}

}

MainActivity的:

package com.bankcomm.test;

import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
private TextView txtMsg;
private String msg = "";
private UpdateReceiver receiver;
private Myservice myservice;
private final static String TAG = MainActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtMsg = (TextView) findViewById(R.id.txtMsg);
this.findViewById(R.id.btnsend).setOnClickListener(this);
this.findViewById(R.id.btnstart).setOnClickListener(this);

// 订阅广播
receiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.android.Hou.msg");
this.registerReceiver(receiver, filter);

}

public class UpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// 获取service传过来的信息
msg = intent.getStringExtra("msg");
System.out.println("msg=============="+msg);
txtMsg.append(msg);
}

}

private ServiceConnection conn = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
myservice = null;
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
myservice = ((Myservice.LocalBinder) service).getService();
Log.i(TAG, "onServiceConnected myService: " + myservice);
}
};

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();

//结束service
if (conn!=null) {
unbindService(conn);
myservice=null;
}
}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, Myservice.class);
int id = v.getId();
switch (id) {
case R.id.btnstart:
//判断服务是否启动
if (false==isServiceRunning(this, Myservice.class.getName())){

Log.i(TAG, "start " + Myservice.class.getSimpleName() + " service");
this.bindService(intent, conn, BIND_AUTO_CREATE);
}
Log.i(TAG, Myservice.class.getName()+" run status: "+isServiceRunning(this, Myservice.class.getName()));
break;
case R.id.btnsend:
//判断服务是否启动
if(false==isServiceRunning(this, Myservice.class.getName())){
Log.i(TAG, "start "+Myservice.class.getSimpleName()+" service");
//启动service
this.bindService(intent, conn, BIND_AUTO_CREATE);

}
Log.i(TAG, Myservice.class.getName()+" run status: "+isServiceRunning(this, Myservice.class.getName()));
Log.i(TAG, "onClick myService: "+myservice); //第一次启动服务时此处为null(小编认为虽然服务已启动成功,但是还没全部初始化)

if (myservice!=null) {
myservice.sendMsgtoServer("i am sending msg to server");
myservice.receiverMsgtoActivity("this is a msg");

}
break;
default:
break;
}

}
/**
* 判断服务是否正在运行
*
* @param context
* @param className 判断的服务名字:包名+类名
* @return true在运行 false 不在运行
*/
public static boolean isServiceRunning(Context context, String className) {
boolean isRunning = false;
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
// 获取所有的服务
List<ActivityManager.RunningServiceInfo> services = activityManager
.getRunningServices(Integer.MAX_VALUE);
if (services != null && services.size() > 0) {
for (ActivityManager.RunningServiceInfo service : services) {
if (className.equals(service.service.getClassName())) {
isRunning = true;
break;
}
}

}
return isRunning;
}

}

MyBroadcastreceiver的:

package com.bankcomm.test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MyBroadcastreceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent service = new Intent(context,Myservice.class);
System.out.println("broadcastreceiver======");
context.startService(service);
}

}

布局和配置文件信息:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/txtMsg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="server"
/>

<Button
android:id="@+id/btnstart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start service" />

<Button
android:id="@+id/btnsend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="send msg to server" />

</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bankcomm.test"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="10" />

<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.bankcomm" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
<activity
android:name="com.bankcomm.test.MainActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Myservice"></service>
<receiver android:name=".MyBroadcastreceiver"></receiver>
</application>

</manifest>

Android组件间的相互调用,布布扣,bubuko.com

时间: 2025-01-31 06:54:39

Android组件间的相互调用的相关文章

两个android程序间的相互调用(apk互调)

通常我们用到的只是activity之间的互相跳转和调用,很少会用到apk级别的互相调用. 往往在一些应用上会用到,比如一个支付系统,可能会有很多的一系列的程序调用到:彩票系统.订票系统.团购网……全部使用一个支付系统会显的更加专业,也能减少不必要的重复. 下面介绍两种方法从一个apk启动另一个apk. 两个互相调用的项目是:demoapk1和demoapk2 demoapk2是被调用的,我们调用它的Pay_Activity.java 所有的界面都是最简单的 这是第一个demoapk1 这是dem

WebView中Js与Android本地函数的相互调用

介绍 随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现. 既然要实现混合开发,那么Js与Android原生函数的相互调用就必不可少了.这里写了一个demo,实现点击html中的图片进行本地展示. 原理 1.Android调用js很简单,直接webView.loadUrl("javascript:JS中的方法名称()");即可. 2.js调用Android方法,需要使用WebView.

Thinkphp中项目下的分组间的相互调用中的配置调用不能跨组

起因: 今天在Home组下面的一个控制器中调用RequestApi组里的控制器下的方法,结果发现一直为Null调用不到,但是当单独打印RequestApi里的方法,是没问题的,郁闷死了.开始检测费了九牛二虎之力就是不行,最后看到RequestApi中调用了配置项,莫非是这个导致的,于是单独打印配置项,可以啊,将配置项在RequestApi中单独写死,运行Home下的方法居然可以了,尼玛,坑爹,配置项的问题. 解决方案: 坚决在应用下新建一个所以分组公用的配置项,将RequestApi中的配置项提

Android组件间通信框架EventBus

事件总线EventBus模式概述 在不使用事件总线的情况下: 在应用中的多个地方,控件经常需要根据某个状态来更新他们显示的内容.这种场景常见的解决方式就是定义一个接口,需要关注该事件的控件来实现这个接口.然后事件触发的地方来注册/取消注册这些对该事件感兴趣的控件.例如,陌陌依赖手机位置信息来获取附近的用户,所以在位置更新管理器(MmLocationManager)中定义了一个接口来监听位置更新的事件(MmLocationListener): interface MmLocationListene

Android组件间通信——EventBus

在Android开发中,组件间通信一直是一个不可忽视的部分.当然,组件之间的通信有很多种方式可以选择,本文就利用EventBus通信的方式进行论述. EventBus是一个第三方框架,它的简单使用分为如下几步: 1. 下载框架源码,并导入工程中. 下载地址:https://github.com/greenrobot/EventBus 如果需要看如何导入并依赖工程,请转到另一篇博文:<Eclipse导入所依赖的Android项目> 2. 定义事件类,并广播事件 例如下面这个自定义事件类Messa

Android 组件间通信--事件驱动

在android中,组件间通信常用的方式: 1.使用广播机制:在主页面中监听特定的广播事件,进行业务逻辑的操作,其他页面只需要根据需求发送广播即可 例如:常用app结构中,左边通常为菜单栏,点击菜单栏,中间页面变化.当点击菜单时发送广播通知容器变化显示的Fragment 2.使用接口方式:activity实现特定的接口,在子类或者Fragment中获取到Activity对象,转换成特定的接口对象,调用接口方法 3.事件驱动方式:EventManager 最近在网上看到EventBus这个开源的工

Android高手进阶教程(二十)之---Android与JavaScript方法相互调用!

在Android中通过WebView控件,可以实现要加载的页面与Android方法相互调用,我们要实现WebView中的addJavascriptInterface方法,这样html才能调用android方法,在这里我个人觉得有点和DWR相似. 为了让大家容易理解,我写了一个简单的Demo,具体步骤如下: 第一步:新建一个Android工程,命名为WebViewDemo(这里我在assets里定义了一个html页面). 第二步:修改main.xml布局文件,增加了一个WebView控件还有But

android组件间共享数据的常用方法

使用Intent在激活组件的时候携带数据,以进行数据的传递 使用广播进行组件间数据的伟递 使用外部存储(sharedPreference,文件,数据库,网络)进行组件间数据共享 使用Static静态成员进行数据传递 Application Context进行程序内组件间数据共享

【Android高级】Android组件间通信库EventBus学习

最近偶然在论坛上看了一个比较厉害的库EventBus,感觉使用起来很爽,不用考虑在Activity还是Fragment,不用担心是不是UI线程,随便怎么通信都行,有网友笑说这简直是Android开发中的第五大组件,通信起来像广播那样神通,但又比广播轻量级多了,所以在这里记下来,以后开发就方便多了. 项目地址:https://github.com/greenrobot/EventBus EventBus主要特点 1. 事件订阅函数不是基于注解(Annotation)的,而是基于命名约定的,在And