Java 如何将字符串从UDP侦听服务传递到MainActivity?
我有一个服务正在侦听绑定到我的Java 如何将字符串从UDP侦听服务传递到MainActivity?,java,android,Java,Android,我有一个服务正在侦听绑定到我的MainActivity(这是应用程序中唯一的活动)的UDP数据包。该服务在它自己的线程上运行,我可以在logcat中看到UDP消息以及解析的消息。我创建了一个setParsedMessage()和一个public getParsedMessage(),以便获取解析后的字符串并将其发送到我的主活动,以便根据解析后的消息更改TextView和ImageView,但是,由于某些原因,它似乎没有检索字符串。我在Developer.Android网站上读到了这个方法,但是我
MainActivity
(这是应用程序中唯一的活动)的UDP数据包。该服务在它自己的线程上运行,我可以在logcat中看到UDP消息以及解析的消息。我创建了一个setParsedMessage()
和一个public getParsedMessage()
,以便获取解析后的字符串并将其发送到我的主活动,以便根据解析后的消息更改TextView
和ImageView
,但是,由于某些原因,它似乎没有检索字符串。我在Developer.Android网站上读到了这个方法,但是我也看到了一些关于使用Handler
来代替它的东西。这是我的密码:
main活动
:
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();
}
}
}
有人能告诉我从服务到主活动获取字符串的最简单方法吗?或者,如果我已经有了字符串,那么我在使用它时哪里出了问题我希望避免将我的服务
重写为意向服务
,除非绝对有必要这样做,因为这是传递给main活动的相对简单的对象
感谢为您的服务类制作以下方法:
private void sendMessage() {
Intent intent = new Intent("message");
intent.putExtra("message", your_message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
并将以下代码放入活动类:
@Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this)
.registerReceiver(mMessageReceiver,
new IntentFilter("message"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String yourMessage = intent.getIntExtra("message",-1);
}
};
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(mMessageReceiver);
super.onPause();
}
注意:-1表示默认值
你可以试着订阅这项服务。我的意思是传递服务调用的一些接口,以通知活动有关更改的信息,下面是我刚刚测试的一个示例:
用户接口
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);
}
}
当然,别忘了取消对destroy的订阅
如果使用处理程序更新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
}
编辑:我忘了保留订户的参考资料,以便以后取消订阅。已从匿名实例更改为字段。您多久收到一次消息?请看以下内容:@vlatkozelka:每100分之一秒一次Miha:服务已绑定。这就是我在评论中询问他多久收到一次消息的原因。每1/100播出一次是行不通的。(据我所知)是否会更新经常导致问题的UI,或者我是否应该编写一个仅在消息值更改时才更改UI的增量函数?我想您应该使用绑定服务,使活动能够直接引用该服务,从而允许对其进行直接调用,与其使用intent,不如在出现消息时根据它更新UI。服务绑定到onCreate()
方法中的活动,我使用Integer parsedMessage=Integer.valueOf(mListenerService.getParsedMessage())直接调用它代码>但它似乎没有更新UI。我将添加一个检查来检查它是否被传递到活动,但我猜它的值是“”
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) {
}
};
}
//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
}