3

我正在实现一个具有服务和活动的android软件,并且我根据youtube视频做了一些代码。但是,当我点击开始按钮,运行按钮他们工作正常。但是,我重新启动服务后(按停止,然后再按启动)程序崩溃。所以任何人都可以帮助我来解决这个问题。Android Activity Service Communication

也有任何方式在Android做服务和活动之间的双向沟通​​? (例如: - 服务获取GPS位置和更改位置0.001,然后ui自动显示编辑后的位置)

请有些人帮我弄清楚这一点。

我的代码: -

MyActivity.java

package com.example.autocomplete.servicemessenger; 

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.os.Message; 
import android.os.Messenger; 
import android.os.RemoteException; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.Toast; 


public class MyActivity extends Activity { 
    boolean status=false; 
    Messenger msngr=null; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_my); 
    } 


    @Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.my, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

public void startMethod(View v){ 
    if (status){ 
     Toast.makeText(getApplicationContext(), "already started", Toast.LENGTH_SHORT).show(); 
    } 
    else { 
     Intent i = new Intent(this, MyService.class); 
     bindService(i, mConnection, Context.BIND_AUTO_CREATE); 
     status = true; 
     Toast.makeText(getApplicationContext(), "start", Toast.LENGTH_SHORT).show(); 
    } 
} 

public void stoptMethod(View v){ 
    if (status) { 
     Intent i = new Intent(this, MyService.class); 
     unbindService(mConnection); 
     stopService(i); 

     mConnection = null; 
     status = false; 
     Toast.makeText(getApplicationContext(), "stop", Toast.LENGTH_SHORT).show(); 
    } 
    else{ 
     Toast.makeText(getApplicationContext(), "already stopped", Toast.LENGTH_SHORT).show(); 
    } 
} 

public void runMethod(View v){ 
    Message ms=Message.obtain(null,1,0,0,0); 
    String s="This is the message by Activity"; 
    Bundle bn=new Bundle(); 
    bn.putString("my_string",s); 
    ms.setData(bn); 
    try { 
     msngr.send(ms); 
    } catch (RemoteException e) { 
     e.printStackTrace(); 
    } 

} 

ServiceConnection mConnection=new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName componentName, IBinder service) { 
     msngr=new Messenger(service); 
     status=true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName componentName) { 
     msngr=null; 
     status=false; 
     Toast.makeText(getApplicationContext(),"Disc",Toast.LENGTH_SHORT).show(); 
    } 
}; 
} 

MyService.java

package com.example.autocomplete.servicemessenger; 

import android.app.Service; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.os.Message; 
import android.os.Messenger; 
import android.text.format.Time; 
import android.widget.Toast; 

import java.util.logging.Handler; 

/** 
* Created by NRV on 9/3/2014. 
*/ 
public class MyService extends Service { 
int val=1; 
@Override 
public IBinder onBind(Intent intent) { 
    return msgnr.getBinder(); 
} 



@Override 
public boolean onUnbind(Intent intent) { 
    stopSelf(); 
    return super.onUnbind(intent); 
} 

class MessageHandler extends android.os.Handler{ 

    public void handleMessage(Message msg){ 
     if (msg.what==val){ 
      Toast.makeText(getBaseContext(),"I am toast in service",Toast.LENGTH_SHORT).show(); 
      Bundle bundle=msg.getData(); 
      String msg_snt=bundle.getString("my_string"); 
      Toast.makeText(getApplicationContext(),"I recv : "+msg_snt,Toast.LENGTH_SHORT).show(); 
     } 
     else{ 
      super.handleMessage(msg); 
     } 

    } 
} 

Messenger msgnr=new Messenger(new MessageHandler()); 


} 

activity_my.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
android:paddingBottom="@dimen/activity_vertical_margin" 
tools:context=".MyActivity"> 

<TextView 
    android:text="@string/hello_world" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/textView" 
    /> 

<Button 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="Start" 
    android:id="@+id/button" 
    android:layout_below="@+id/textView" 
    android:layout_marginTop="93dp" 
    android:layout_toLeftOf="@+id/button2" 
    android:onClick="startMethod"/> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Stop" 
    android:id="@+id/button2" 
    android:layout_below="@+id/button" 
    android:layout_alignParentRight="true" 
    android:layout_marginRight="106dp" 
    android:onClick="stoptMethod"/> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Run" 
    android:id="@+id/button3" 
    android:layout_below="@+id/button2" 
    android:layout_alignParentLeft="true" 
    android:onClick="runMethod"/> 

</RelativeLayout> 

回答

1

当你在进行mConnection = NULLstoptMethod(视图V),当你正试图从绑定startMethod(视图V)服务它试图绑定mConnection(这是空)服务。因此它正在崩溃。 修复:注释掉mConnection = nullstoptMethod(View v)。 也不需要

Intent i = new Intent(this,MyService.class); stopService(ⅰ);在stoptMethod(View v)

当应用程序组件通过调用bindService()绑定一个服务时,服务是“绑定”的。绑定服务提供了一个客户端 - 服务器接口,允许组件与服务进行交互,发送请求,获取结果,甚至跨进程使用进程间通信(IPC)进行交互。绑定服务只在另一个应用程序组件绑定到它时才运行。多个组件可以立即绑定到服务,但是当它们全部解除绑定时,服务将被销毁。请致电bound-servicesServices