Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将字符串从UDP侦听服务传递到MainActivity?_Java_Android - Fatal编程技术网

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
  }