我有一個活動,我想用它來顯示從我的服務發送的數據。每次服務向活動發送消息時,活動都會更新文本視圖。用戶可以使用活動中的按鈕啓動和停止服務(服務由用戶明確啓動/停止)。目前,我的活動綁定到onResume()中的服務,並在onDestroy()中取消綁定,這似乎正在工作。如何將我的Activity綁定到我當前在Android中運行的Service?
當我啓動服務時,按下後退按鈕,然後再次嘗試重點活動時,會出現問題。我遇到了一項新的活動,該活動並未被服務更新,但似乎能夠向服務發送消息(我已經注意到這些來自我的處理程序中的日誌(這個短語使我發笑的男孩)]。理想情況下,我希望只有一個活動實例存在並保持綁定到服務,但我絕對不希望看到活動跟不上更新。我用<activity android:launchMode="singleTop">
更新了我的清單,但我不確定這對事情有什麼幫助。我能做些什麼來確保我的活動重新恢復到現有的服務實例,以便以後恢復? (我想通過消息傳遞實現這一點,我不想實現數據庫或使用sharedprefereces這個位)。我在下面包括我的代碼 - 我對服務比較陌生,所以對我來說很簡單。乾杯。
可選額外: 我的目標是從startService()開始持續運行的服務,並且活動的重點是可選的,但會立即顯示服務的最新信息。我相信我正在尋找的是前臺服務。這不是問題的一部分,但請讓我知道,如果你認爲你的答案可能會阻止我實現這一點。
MainActivity.java:
public class MainActivity extends Activity
{
private static final String debug = "MainActivity";
private boolean bound = false;
TextView mTextView;
protected Messenger outMessenger;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(debug, "onCreate called");
mTextView = (TextView) findViewById(R.id.textView1);
Button bind = (Button) findViewById(R.id.bind);
Button unbind = (Button) findViewById(R.id.unbind);
bind.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("ACTION", "START");
message.setData(bundle);
try
{
outMessenger.send(message);
} catch (RemoteException e)
{
Log.d(debug, "She can't reach the service captain!");
}
}
});
unbind.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("ACTION", "STOP");
message.setData(bundle);
try
{
outMessenger.send(message);
} catch (RemoteException e)
{
Log.d(debug, "She can't reach the service captain!");
}
}
});
}
@Override
public void onPause()
{
super.onPause();
}
@Override
public void onResume()
{
super.onResume();
doBindService();
}
public void onDestroy()
{
super.onDestroy();
Log.i(debug, "onDestroy Called");
doUnbindService();
}
private void doBindService()
{
Log.i(debug, "Attempting to bind");
bound = true;
Intent i = new Intent(this, MyService.class);
i.putExtra("MESSENGER", new Messenger(mHandler));
bindService(i, mConnection, Context.BIND_AUTO_CREATE);
}
private void doUnbindService()
{
Log.i(debug, "Attempting to unbind");
if (bound)
{
bound = false;
unbindService(mConnection);
}
}
private Handler mHandler = new Handler()
{
public void handleMessage(Message message)
{
Log.d(debug, "Got a message!");
Bundle data = message.getData();
if (data != null)
{
Log.i(debug, "This data ain't null!");
if (data.containsKey("MESSAGE"))
{
mTextView.setText(data.getString("MESSAGE"));
}
}
}
};
private ServiceConnection mConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder binder)
{
Log.i(debug, "Service connected!");
outMessenger = new Messenger(binder);
}
@Override
public void onServiceDisconnected(ComponentName className)
{
Log.d(debug, "Service Disconnected!");
}
};
}
MyService.java
public class MyService extends Service
{
private static final String debug = "MyService";
private Messenger inMessenger = new Messenger(new IncomingHandler());
Messenger outMessenger;
private boolean bound = false;
int secret = 0;
@Override
public void onCreate()
{
Log.d(debug , "MyService Created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(debug , "onStartCommand called");
handleCommand(intent);
return START_STICKY;
}
Handler handler = new Handler();
public boolean running;
void handleCommand(Intent i)
{
Runnable r = new Runnable()
{
public void run()
{
updateResultsInUi();
if (running)
{
handler.postDelayed(this, 500);
}
}
};
r.run();
}
void updateResultsInUi()
{
Bundle bundle = new Bundle();
bundle.putString("MESSAGE",
Integer.toString(secret = ++secret % 10));
Message message = new Message();
message.setData(bundle);
if (bound)
{
try
{
outMessenger.send(message);
}
catch (RemoteException e)
{
Log.d(debug, "Messaging failed");
}
}
else
{
Log.d(debug, "Not connected, so not messaging!");
}
}
@Override
public IBinder onBind(Intent intent)
{
Log.i(debug, "Bound");
bound = true;
Bundle extras = intent.getExtras();
outMessenger = (Messenger) extras.get("MESSENGER");
return inMessenger.getBinder();
}
@Override
public void onRebind(Intent i)
{
bound = true;
Bundle extras = i.getExtras();
outMessenger = (Messenger) extras.get("MESSENGER");
}
@Override
public boolean onUnbind(Intent i)
{
Log.d(debug, "onUnbind() called.");
bound = false;
outMessenger = null;
return true;
}
class IncomingHandler extends Handler
{
@Override
public void handleMessage(Message msg)
{
Log.d(debug, "Got message");
Bundle data = msg.getData();
if (data.containsKey("ACTION"))
{
if ("START".equals(data.getString("ACTION")))
{
if (!running)
{
running = true;
Intent i = new Intent(getApplicationContext(), MyService.class);
startService(i);
}
else
{
Log.d(debug, "We're already up and running!");
}
}
else if ("STOP".equals(data.getString("ACTION")))
{
running = false;
Intent i = new Intent(getApplicationContext(), MyService.class);
stopService(i);
}
}
}
}
}
AndroidManifest.xml中
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tests.servicetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.tests.servicetest.MainActivity"
android:label="@string/title_activity_main"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.tests.servicetest.MyService"
android:process=":inaneService">
</service>
</application>
</manifest>
而對於那些你們誰想要運行它,activity_main.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" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="@dimen/padding_medium"
android:text="@string/hello_world"
tools:context=".MainActivity" />
<Button
android:id="@+id/bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:text="Start" />
<Button
android:id="@+id/unbind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/bind"
android:text="Stop" />
</RelativeLayout>
的問題是,在onRebind意圖是不是新的傳遞給bindService,但原來的一個,在firt綁定使用。喬納斯的答案是要走的路。 – ecdpalma 2013-04-24 14:30:13