- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试将 Activity 绑定(bind)到 LocalService 以与之交互。但是在我的 Activity 中,我只能调用 LocalBinder 中定义的方法,而不能调用 LocalService 中定义的方法。我做错了什么?
不是从头开始我读了另一个 question我已经阅读了一些如何code some sample code我的代码类似于该示例代码。我也一直在阅读一些 Service Documentation为方便起见,这里引用了文档该部分的一小段内容:
“当应用程序组件通过调用 bindService() 绑定(bind)到服务时,服务被“绑定(bind)”。绑定(bind)服务提供客户端-服务器接口(interface),允许组件与服务交互、发送请求、获取结果,,甚至通过进程间通信 (IPC) 跨进程执行此操作。绑定(bind)服务仅在另一个应用程序组件绑定(bind)到它时运行。多个组件可以同时绑定(bind)到该服务,但是当它们全部解除绑定(bind)时,服务就会被破坏。”
可是我做不到。如上所述,我能做的最好的事情就是在我的 LocalBinder 中定义我的 Activity 调用方法。我没有取得像上面黑色突出显示的部分那样的成就。
如果有帮助,这里是我的代码的相关部分。
要绑定(bind)的 LocalService:
/**************************************************************************************************
* Filename: LocalService.java
* Project name: Local Service Sample
* Application name: Local Service
* Description: This file contains the LocalService (extends Service) for our Local Service app
**************************************************************************************************/
package com.marie.localservicesample;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
public class LocalService extends Service {
private NotificationManager mNM;
// Unique Identification Number for the Notification.
// We use it on Notification start, and to cancel it.
private int NOTIFICATION = R.string.local_service_started;
// just some arbitrary numbers for test purposes
public static int statusCode = 99;
public static int emptyMsg = 549;
// I get my Extras from onStartCommand and use in ServiceWorker() thread
public static final String EXTRA_MAC = "com.marie.localservicesample.EXTRA_MAC";
private String macString;
public static final String EXTRA_MESSENGER = "com.marie.localservicesample.EXTRA_MESSENGER";
private Messenger messenger;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
//private static final String macString = "00:06:66:02:D0:EC";
Boolean stop_receive_data = false;
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example - or not because
// this is a local service
private final IBinder mBinder = new LocalBinder();
@Override
public IBinder onBind(Intent intent) {
Log.i("onBind", "called in LocalService" );
Log.i("onBind", "intent: " + intent.toString());
Log.i("onBind", "mBinder: " + mBinder);
return mBinder;
}
@Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// Display a notification about us starting. We put an icon in the status bar.
showNotification();
}
// Call this at the end of onStartCommand() after we got the Extras
public void afterStartCommand() {
Thread thr = new Thread(null, new ServiceWorker(), "LocalService");
thr.start();
}
/*
* This is the ServiceWorker thread that passes messages to the handler defined in
* the Controller activity.
*/
class ServiceWorker implements Runnable
{
public void run() {
// do background processing here... something simple
Looper.prepare();
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice btDevice = btAdapter.getRemoteDevice(macString);
BluetoothSocket btSocket = null;
InputStream btIstream = null;
OutputStream btOstream = null;
try {
btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
btSocket.connect();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
btIstream = btSocket.getInputStream();
btOstream = btSocket.getOutputStream();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
int data = btIstream.read();
// reset the bluetooth device
while (data != 63) {
Log.d("LocalService", "resetting bluetooth device");
btOstream.write('r');
data = btIstream.read();
}
StringBuffer strBuffer = new StringBuffer("");
Boolean dataBegin = false;
int ndxPlus = 0;
while (data != -1) {
char printableB = (char) data;
if (data < 32 || data > 126) {
//printableB = ' ';
}
//Log.d("LocalService", Character.toString(printableB) + "(" + data + ")");
if (data == 63) {
btOstream.write('$');
btOstream.write(',');
}
if (data == 45) {
btOstream.write('1');
btOstream.write(',');
dataBegin = true;
}
if (dataBegin == true) {
strBuffer = strBuffer.append(Character.toString(printableB));
}
if (data == 13) {
dataBegin = false;
//Log.d("LocalServiceDataString", strBuffer.toString());
// send data to the handler to plot the data
Message msg = Message.obtain();
msg.what = Controller.MESSAGE_MAC;
msg.obj = strBuffer;
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
strBuffer = new StringBuffer("");
if (ndxPlus < 0) {
btOstream.write('+');
ndxPlus++;
}
}
data = btIstream.read();
if (stop_receive_data) data = -1;
}
} catch (IOException e1) {
e1.printStackTrace();
}
try {
btSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
LocalService.this.stopSelf();
Looper.loop();
// stop the service when done...
// Or use the unbindBtn in the MainActivity class?
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
Bundle extras = intent.getExtras();
messenger = (Messenger)extras.get(EXTRA_MESSENGER);
macString = extras.getString(EXTRA_MAC);
afterStartCommand();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
@Override
public void onDestroy() {
// Cancel the persistent notification.
mNM.cancel(NOTIFICATION);
stop_receive_data = true;
// Tell the user we stopped.
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
}
/**
* Show a notification while this service is running.
*/
private void showNotification() {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.local_service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.stat_sample, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Controller.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent);
// Send the notification.
mNM.notify(NOTIFICATION, notification);
}
}
绑定(bind)到本地服务的 Activity :
/**************************************************************************************************
* Filename: Binding.java
* Project name: Local Service Sample
* Application name: Local Service
* Description: This file contains the Binding class for our Local Service application
**************************************************************************************************/
package com.marie.localservicesample;
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.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
/*
* Example of binding and unbinding to the local service.
* This demonstrates the implementation of a service which the client will
* bind to, receiving an object through which it can communicate with the service.
*/
public class Binding extends Activity {
private ILocalBinder mBoundService;
private boolean mIsBound;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = (ILocalBinder)service;
int statusCode = mBoundService.getStatusCode();
Log.d("Binding.java","called onServiceConnected. statusCode: " + statusCode);
Toast.makeText(Binding.this, R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mBoundService = null;
Log.d("Binding", "called onServiceDisconnected");
Toast.makeText(Binding.this, R.string.local_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
int statusCode = mBoundService.getStatusCode();
if (statusCode != 0) Log.d("doUnbindService", "Binding.java statusCode: " + statusCode);
// Tell the user we did an unbind
Toast.makeText(this, R.string.local_service_unbound, Toast.LENGTH_SHORT).show();
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_service_binding);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
}
private OnClickListener mBindListener = new OnClickListener() {
public void onClick(View v) {
doBindService();
}
};
private OnClickListener mUnbindListener = new OnClickListener() {
public void onClick(View v) {
doUnbindService();
}
};
@Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
}
我的 ILocalBinder 和 LocalBinder:
/**************************************************************************************************
* Filename: ILocalBinder.java
* Project name: Local Service Sample
* Application name: Local Service
* Description: This file contains an example interface for my LocalBinder
**************************************************************************************************/
package com.marie.localservicesample;
public interface ILocalBinder {
public int getStatusCode();
}
/**************************************************************************************************
* Filename: LocalBinder.java
* Project name: Local Service Sample
* Application name: Local Service
* Description: This file contains the LocalBinder class for our Local Service application
**************************************************************************************************/
package com.marie.localservicesample;
import android.os.Binder;
import com.marie.localservicesample.LocalService;
/**
* Class for clients to access. Because we know this service always
* runs in the same process as its clients, we don't need to deal with
* IPC.
*/
public class LocalBinder extends Binder implements ILocalBinder {
@Override
public int getStatusCode() {
return LocalService.statusCode;
}
}
谢谢!
最佳答案
只需将他们拥有的 Binder 类代码复制到您的服务中,而不是为其创建一个单独的文件:(在 LocalService 类声明中)
public class LocalService {
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
/**
* Class for clients to access. Because we know this service always
* runs in the same process as its clients, we don't need to deal with
* IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
return LocalService.this;
}
}
...
}
然后:
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = ((LocalService.LocalBinder)service).getService();
现在您可以使用 mBoundService 直接访问您的服务。
关于android - 如何将Activity绑定(bind)到Service,并从Activity中控制和管理Service,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6723026/
我对 Android 很陌生,如果问题重复,请避免并发送链接。有三个 Activity A、B 和 C。 Activity A 获取一个用户名,我想在 Activity C 中显示该用户名,但我想先运
我正在尝试制作记事本应用程序,因此每次打开新笔记时,布局都会相同。另外, Activity 的数量(新注释)不应定义得尽可能多 最佳答案 如果 Activity 始终相同,您可能应该创建一个适配器,允
我有 3 个 Activity 。 主窗口 5 个按钮 在按钮的主窗口中按下此窗口打开(将其称为父窗口) 在父窗口按钮上按下此窗口打开调用它作为结束子窗口。 现在从子窗口我从父窗口获取值如下:
我遇到了一个 Activity backstack 问题。假设我的后台有 5 个 Activity :比如 Activity A、 Activity B、 Activity C、 Activity D
我正在寻找必须具有以下附加特征的 JMS 提供程序: 采用多代理,所有代理都必须处于事件状态(无单点故障) 仅在两台机器上进行扩展就足以满足我们的需求 能够保证订购(如果 1 个生产者 + 1 个消费
假设,我有一个由 TabHost 组成的选项卡 Activity 。 TabHost 包含 2 个选项卡,每两个选项卡都有一个 Activity 组。每个 Activity 组包含一项 Activit
我正在开发一个应用程序,我需要根据某些操作导航到特定 Activity 。这是一张图片 我的第一个 Activity 是 ReadingActivity。基于某些操作,用户将被带到 NewProjec
我创建了一个与服务器异步通信的应用程序。当应用程序发出服务器请求时,将创建一个带有“正在加载”通知的新对话框( Activity )。主要 Activity 实现了处理服务器响应的方法,我想在主要 A
我想在我的所有应用程序 Activity 中显示相同的选项菜单。我创建了一个实现菜单的通用 Activity ,并且我所有的进一步 Activity 都扩展了它。 问题:当我需要扩展其他特定 Acti
我有四个 Activity ,即 java 文件 - Activity1.java、activity2.java、activity3.java、activity4.java 和 xml 文件 - Ac
我有两个 Activity 。我想将数据从第二个 Activity 发送到上一个 Activity 。第一个 Activity 有自定义 ListView 和 bean 类。当我点击第二个 Activ
根 Activity 是堆栈中当前的第一个 Activity 还是 list 中指定为启动 Activity 的 Activity ? 支持应用程序 P 在启动时启动 Activity A。然后 A
你好 我想知道您在绘制 Activity 图选择“Activity ”时考虑了哪些关键点? 您如何从要建模的问题中选择 Activity ? 谢谢 最佳答案 Activity 图用于对正在开发的系统和
如何从主 Activity 启动 Activity 并在子 Activity 返回主 Activity 中退出操作后返回主 Activity ? 我已将子 Activity 作为启动器 Intent
我的工作流程如下: 登录 Activity -> ActivityB -> ActivityC -> ActivityD 我想将数据从LoginActivity传递到ActivityD,但不直接传递到
我之前曾尝试获得此问题的答案,但找不到可以解决我的问题的答案。我正在制作保存圆盘高尔夫球分数的应用程序。我的 MainActivity 有 4 个按钮。新比赛、恢复比赛、类(class)和球员。 At
我有一个 tts 非 UI 类和 Activity 类。现在在 Activity 类中,我有一个按钮,用户可以从中选择男声或女声,具体取决于我想要将字符串传递给 tts 类的选择,然后一次tts 类根
问题有点复杂,首先, Activity A 和 Activity B 的 list 中都有 android:noHistory = true 。我有一个自定义 serialized 类,假设 MyCl
在我的应用程序中,我有两个 Activity (AuthenticationActivity 和 MainActivity),每个 Activity 都有一个导航图和大量 fragment 。我创建了
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How can i use compose email activity in tabView? 我想在选项
我是一名优秀的程序员,十分优秀!