ServiceConnection.onServiceConnected() nie aufgerufen, nachdem die Bindung an Dienst gestartet
In einem Spiel habe ich Folgendes Szenario:
- Von der Haupt-Spiel
Activity
beginnt der player die mehrere Spiel-Aufgaben, die im hintergrund laufen mit unterschiedlicher Dauer. - Der Spieler sollte in der Lage sein, um den Fortschritt des Laufenden Spiel-Aufgaben in einer separaten
View
.
Dazu, ich habe zwei Activity
s und eine Service
wie folgt definiert:
-
Service ProgressService
Griffen mehrereProgressBar
s gleichzeitig laufen parallele threads. -
Activity WorkScreen2
erstellt ein Spiel, Aufgabe, startet dieService
mitstartService()
mit der Aufgabe, die übergebenen Parameter in einBundle
. -
Activity ProgressScreen
bindet an dieService
zum abrufen und anzeigen derProgressBar
s der Laufenden Aufgaben. -
Beide Aktivitäten laufen unter eigenen
TabHost
s von einemTabActivity
.
Das problem das ich habe ist, dass die ServiceConnection.onServiceConnected()
- Methode niemals aufgerufen wird. Ich bekomme eine Java.lang.NullPointerException
weil ich versuche, eine Methode aufrufen die Service
Objekt, das zugewiesen werden soll, die in dieser Methode. Siehe code unten.
Benutze ich getApplicationContext().bindService()
zu binden Activity
zu den Service
weil TabSpec
kann nicht binden an Services
. Diese Methode gibt true
. Deshalb, die Bindung erfolgreich ist.
Hier ist die Service
:
public class ProgressService extends Service implements GameConstants {
public static final String BROADCAST_PROGRESS = "com.mycompany.android.mygame.progressbroadcast";
private static final long UPDATE_INTERVAL = 500;
private IBinder mBinder;
private List<ProgressBar> mProgressBarList;
private List<String> mStaffNameList;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
ProgressBar progressBar = new ProgressBar(ProgressService.this);
mProgressBarList.add(progressBar);
Bundle bundle = msg.getData();
String staffName = bundle.getString(WorkScreen2.STAFF_NAME);
mStaffNameList.add(staffName);
int taskDurationMillis = bundle.getInt(WorkScreen2.TASK_DURATION) * 1000;
progressBar.setMax(taskDurationMillis / 1000);
long startTimeMillis = SystemClock.uptimeMillis();
long elapsedTimeMillis = SystemClock.uptimeMillis()
- startTimeMillis;
Intent intent = new Intent();
intent.setAction(BROADCAST_PROGRESS);
while (elapsedTimeMillis < taskDurationMillis) {
try {
Thread.sleep(UPDATE_INTERVAL);
} catch (InterruptedException e) {
e.printStackTrace();
}
elapsedTimeMillis = SystemClock.uptimeMillis()
- startTimeMillis;
int elapsedTimeSeconds = (int) elapsedTimeMillis / 1000;
progressBar.setProgress(elapsedTimeSeconds);
sendBroadcast(intent);
}
progressBar.setVisibility(View.GONE);
mProgressBarList.remove(progressBar);
mStaffNameList.remove(staffName);
sendBroadcast(intent);
if (mProgressBarList.isEmpty()) {
stopSelf(msg.arg1);
}
}
}
@Override
public void onCreate() {
super.onCreate();
mBinder = new ProgressServiceBinder();
mProgressBarList = Collections
.synchronizedList(new ArrayList<ProgressBar>());
mStaffNameList = Collections.synchronizedList(new ArrayList<String>());
}
/*
* Creates a thread for each game task with parameters passed in
* <code>intent</code>
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "starting service", Toast.LENGTH_LONG).show();
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Handler serviceHandler = new ServiceHandler(thread.getLooper());
Message msg = serviceHandler.obtainMessage();
msg.arg1 = startId;
msg.setData(intent.getExtras());
serviceHandler.sendMessage(msg);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class ProgressServiceBinder extends Binder {
ProgressService getService() {
return ProgressService.this;
}
}
public List<ProgressBar> getProgressBarList() {
return mProgressBarList;
}
public List<String> getStaffNameList() {
return mStaffNameList;
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service done", Toast.LENGTH_SHORT).show();
}
}
- Und dies ist die Activity
bindet:
public class ProgressScreen extends ListActivity {
private final String TAG = "ProgressScreen";
private ProgressScreenAdapter mAdapter;
private ProgressService mProgressService;
private List<ProgressBar> mProgressBarList;
private List<String> mStaffNameList;
@Override
public void onCreate(Bundle bundle) {
Log.i(TAG, "ProgressScreen oncreate");
super.onCreate(bundle);
setContentView(R.layout.progress_screen_layout);
IntentFilter filter = new IntentFilter();
filter.addAction(ProgressService.BROADCAST_PROGRESS);
registerReceiver(receiver, filter);
doBindService();
mAdapter = new ProgressScreenAdapter(this, mStaffNameList, mProgressBarList);
setListAdapter(mAdapter); //Returns true
/*
* This is where I get the NullPointerException
* mProgressService is null here
*/
mProgressBarList = mProgressService.getProgressBarList();
mStaffNameList = mProgressService.getStaffNameList();
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(ProgressService.BROADCAST_PROGRESS);
registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
boolean doBindService() {
return getApplicationContext().bindService(new Intent(this, ProgressService.class), mConnection, Context.BIND_AUTO_CREATE);
}
void doUnbindService() {
getApplicationContext().unbindService(mConnection);
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
mProgressService = ((ProgressService.ProgressServiceBinder) binder).getService();
Toast.makeText(ProgressScreen.this, "Connected to ProgressService", Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName name) {
mProgressService = null;
}
};
private BroadcastReceiver receiver = new BroadcastReceiver () {
@Override
public void onReceive(Context context, Intent intent) {
mAdapter.notifyDataSetChanged();
}
};
}
Und die Service
gestartet wird von der Haupt - Activity
wie folgt:
Intent intent = new Intent(WorkScreen2.this, ProgressService.class);
intent.putExtra(TASK_DURATION, task.getDuration());
intent.putExtra(STAFF_NAME, staff.getName());
startService(intent);
Den AndroidManifest.xml
enthält
<service
android:name=".ProgressService"
android:label="@string/progress_service">
</service>
InformationsquelleAutor Wesam | 2012-02-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
ServiceConnection die onServiceConnected() heißt, aber niemand garantiert, dass es genannt werden vor onCreate setzt die Ausführung Fort. Also, was hier passiert - Sie erfolgreich binden an den service (das ist, warum onBind gibt true zurück), aber Sie sind nicht vollständig verbunden - onServiceConnected() noch nicht aufgerufen wurde, so dass Ihre lokalen mProgressService Objekt ist noch nicht zuerst entsprechend formatiert, und daher bekommst du die NullPointerException.
Lösung:
Verschieben Sie diese zwei Zeilen:
vom onCreate() zu onServiceConnected() Funktion (verwenden Sie das service-Objekt nach es ist initialisiert, in onServiceConnected()).
Zweite dass. Ich habe dicking um mit diesem die ganze Nacht und dieser schließlich hob die Hand. Danke!
InformationsquelleAutor Milan Krstic
Überprüfen AndroidManifest.xml dein und hinzufügen von service, dass Sie versucht haben, zu binden.
Service
element 'AndroidManifest.xml" für dieService
ich bin versucht zu binden. Die Bindung ist erfolgreich, dabindService()
zurücktrue
.Ich konnte nicht danke mehr Herr Oldtimer : )
InformationsquelleAutor oldtimer
Haben Sie zurückkehren Ihren Binder innere Klasse von
InformationsquelleAutor Chathuranga Rathnayake