gpt4 book ai didi

java - 如何将字符串从 UDP 监听服务传递到 MainActivity?

转载 作者:行者123 更新时间:2023-12-02 12:34:16 24 4
gpt4 key购买 nike

我有一个服务监听 UDP 数据包,该数据包绑定(bind)到我的 MainActivity(这是应用程序中的唯一 Activity )。该服务在自己的线程上运行,我可以在 logcat 中看到 UDP 消息以及解析的消息。我创建了一个 setParsedMessage() 和一个 public getParsedMessage() 来获取解析后的字符串并将其发送到我的主要 Activity ,以便更改 TextView 和一个 ImageView 取决于解析的消息是什么,但是由于某种原因它似乎没有检索 String 。我在 Developer.Android 网站上读到了有关此方法的信息,但我也看到了一些有关使用 Handler 来执行此操作的内容。这是我的代码:

主 Activity :

public class MainActivity extends Activity {

AlertAssignments mAlertAssignments;



Button startListeningButton;

boolean started;
int counter;
boolean mBound = false;
Context context;
ListenerService mListenerService;

TextView mTextView;
TextView mBlinkView;
ImageView mImageView;


private StartListening _StartListeningTask;
String messageFromService = "";




@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//start listener service
Intent listenerServiceIntent = new Intent(MainActivity.this, ListenerService.class);
this.bindService(listenerServiceIntent, mConnection, Context.BIND_AUTO_CREATE);

mImageView = (ImageView) findViewById(R.id.image_view);
mTextView = (TextView) findViewById(R.id.alert_text);
mBlinkView = (TextView) findViewById(R.id.blinking_text);
Animation mAnimation = new AlphaAnimation(0.0f, 1.0f);
mAnimation.setDuration(50);
mAnimation.setStartOffset(20);
mAnimation.setRepeatCount(Animation.INFINITE);
mAnimation.setRepeatMode(Animation.REVERSE);
mBlinkView.startAnimation(mAnimation); //animation value
mAlertAssignments = new AlertAssignments();

}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
ListenerService.LocalBinder binder = (ListenerService.LocalBinder) service;
mListenerService = binder.getService();
mBound = true;
if(mBound) {
Log.e("UDP", "Service has been bound successfully");
}
else {
Log.e("UDP", "Service has not been bound");
}

readFromService();
}

@Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};

@Override
protected void onStart() {
super.onStart();

}


@Override
protected void onStop() {
super.onStop();
//unbind from service
if(mBound) {
this.unbindService(mConnection);
mBound = false;
}

}

private void readFromService() {
try {
Integer parsedMessage = Integer.valueOf(mListenerService.getParsedMessage());
mImageView.setImageResource(mAlertAssignments.alarmImages[parsedMessage]);

if(parsedMessage >= 10 && parsedMessage <= 19 && parsedMessage != 0) {
mTextView.setText(mAlertAssignments.alertTextMessages[parsedMessage]);
} else {
mBlinkView.setText(mAlertAssignments.alertTextMessages[parsedMessage]);
}
} catch(NumberFormatException e) {
e.printStackTrace();
}

}


}

我读过这样使用公共(public) setter/getter :
Integer parsedMessage = Integer.valueOf(mListenerService.getParsedMessage());
将允许我访问 mListenerService.getParsedMessage 的字符串值,但我猜测这可能仅适用于已启动的服务,不适用于绑定(bind)服务。

AlertAssignments 是一个简单的枚举,它使用序数数组将图像和字符串绑定(bind)到值,因此 mImageView.setImageResource(mAlertAssignments.alarmImages[parsedMessage]) 将设置 ImageView 到图像。最后,这是服务:

public class ListenerService extends Service{
public String the_alarm_S;
public String parsedMessage = "";
private final IBinder mBinder = new LocalBinder();


public class LocalBinder extends Binder {
ListenerService getService() {
return ListenerService.this;
}
}

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

DatagramSocket socket;

Thread UDPBroadcastThread;

void startListenForUDPBroadcast() {
UDPBroadcastThread = new Thread(new Runnable() {
public void run() {
try {
while (shouldRestartSocketListen) {
try {
socket = new DatagramSocket(12001);
socket.setReuseAddress(true);
String message = "";

byte[] recvBuf = new byte[1024];
DatagramPacket packet = new DatagramPacket(recvBuf, 1024);
Log.e("UDP", "Waiting for UDP broadcast");
try {
socket.receive(packet);
Log.e("UDP", "Received Packet");
} catch (IOException e) {
e.printStackTrace();

}
message = new String(packet.getData());

Log.e("UDP", "Got UDB broadcast message: " + message);

setParsedMessage(message);

if(socket != null) {
socket.close();
}
} catch (SocketException e) {
e.printStackTrace();
}
}
//if (!shouldListenForUDPBroadcast) throw new ThreadDeath();
} catch (Exception e) {
Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
}
}
});
UDPBroadcastThread.start();
}

private Boolean shouldRestartSocketListen = true;

private void setParsedMessage(String messageContents) {
the_alarm_S = messageContents;
String parseMessage[] = the_alarm_S.split("!!!");
Log.e("UDP", "Parsed message with value " + parseMessage[1]);
parsedMessage = parseMessage[1];

}
public String getParsedMessage() {
return parsedMessage;
}

private void stopListen() {
shouldRestartSocketListen = false;
if(socket != null) {
socket.close();
}
}

@Override
public void onCreate() {
startListenForUDPBroadcast();
}

@Override
public void onDestroy() {
stopListen();
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
shouldRestartSocketListen = true;
startListenForUDPBroadcast();
Log.i("UDP", "Service started");
return START_STICKY;
}
}

有人可以给我从服务到主要 Activity 获取字符串的最简单方法吗?或者如果我已经有了它,我在使用它时会出错吗? 我希望避免将我的 Service 重写为 IntentService ,除非绝对有必要这样做,因为这是一个传递给 的相对简单的对象主要 Activity

谢谢

最佳答案

您可以尝试订阅该服务。我的意思是传递服务调用的一些接口(interface)来通知 Activity 有关更改的信息,这是我刚刚测试的示例:

订阅者界面

public interface ServiceSubscriber {
void messageCallback(String message);
}

使用订阅者订阅服务

public class TestService extends Service {

ArrayList<ServiceSubscriber> subscribers = new ArrayList<>();
private TestBinder testBinder = new TestBinder();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(){
@Override
public void run() {
while(true){
//this is where you are receiving UDP packets
doStuff();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}

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

private void doStuff() {
System.out.println("Service is doing stuff!");
//loop through your subscribers and notify them of your changes
//a loop here isn't very costly, if there aren't many subscribers
for (ServiceSubscriber subscriber : subscribers) {
subscriber.messageCallback("I'm doing stuff");
}

}

public class TestBinder extends Binder {

public TestService getService() {
return TestService.this;
}
}

public void subscribeToMessages(ServiceSubscriber subscriber) {
subscribers.add(subscriber);
}


public void unSubscribeToMessages(ServiceSubscriber subscriber) {
subscribers.remove(subscriber);
}
}

现在对于通常的绑定(bind) Activity ,您可以在其中定义需要对消息回调执行的操作:

public class MainActivity extends AppCompatActivity {
private TestService testService;
private Subscriber subscriber;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
protected void onStart() {
super.onStart();

bindService(new Intent(this, TestService.class),serviceConnection, Context.BIND_AUTO_CREATE);
}

private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
testService = ((TestService.TestBinder)service).getService();
subscriber = new ServiceSubscriber() {
@Override
public void messageCallback(String message) {
//I'm just printing out the message received
//Be careful if you need to do UI stuff to use a
//Handler
System.out.println(message);
}
}
testService.subscribeToMessages(subscriber );
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
};

}

当然,不要忘记在销毁时取消订阅。

如果您使用处理程序更新 UI,通常不会破坏您的应用

 //activity fields
Handler handler



//in activity constructor
handler = new Handler();

//update UI by calling
handler.post(new Runnable(){
@Override
public void run(){
//update the UI here
}

编辑:我忘记保留订阅者的引用信息,以便稍后取消订阅。从匿名实例更改为字段。

关于java - 如何将字符串从 UDP 监听服务传递到 MainActivity?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45197983/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com