在游戏应用程序中,我有以下场景:
>从主游戏Activity中,玩家开始在后台运行的不同持续时间的几个游戏任务.
>玩家应该能够在单独的视图中查看正在运行的游戏任务的进度.
为此,我创建了两个Activity和一个Service,定义如下:
> Service ProgressService处理在并行线程上同时运行的多个Progressbars.
> Activity WorkScreen2创建一个游戏任务,使用带有在Bundle中传递的任务参数的startService()启动服务.
> Activity ProgressScreen绑定到服务以获取并显示正在运行的任务的Progressbars.
>这两个活动都在一个tabactivity的单独TabHosts下运行.
我遇到的问题是从不调用ServiceConnection.onServiceConnected()方法.我得到一个Java.lang.NullPointerException,因为我尝试调用应该在此方法中分配的Service对象的方法.见下面的代码.
我使用getApplicationContext().bindService()将Activity绑定到服务,因为TabSpec
cannot bind to Services
.此方法返回true.因此,绑定是成功的.
这是服务:
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(); }}
这是绑定它的活动:
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(); } };}
服务从主要活动开始如下:
Intent intent = new Intent(WorkScreen2.this, ProgressService.class);intent.putExtra(TASK_DURATION, task.getDuration());intent.putExtra(STAFF_name, staff.getname());startService(intent);
AndroIDManifest.xml包含
<service androID:name=".ProgressService" androID:label="@string/progress_service"></service>
解决方法:
调用ServiceConnection的onServiceConnected(),但没有人保证在onCreate继续执行之前调用它.那么,这里发生了什么 – 你成功地绑定到服务(这就是为什么onBind返回true),但你还没有完全连接 – 尚未调用onServiceConnected(),因此你的本地mProgressService对象尚未初始化,因此你得到NullPointerException.
解:
移动这两行:
mProgressbarList = mProgressService.getProgressbarList();mStaffnameList = mProgressService.getStaffnameList();
从onCreate()到onServiceConnected()函数(在onServiceConnected()中初始化后使用服务对象).
总结以上是内存溢出为你收集整理的android – ServiceConnection.onServiceConnected()在绑定到已启动的服务后从未调用过全部内容,希望文章能够帮你解决android – ServiceConnection.onServiceConnected()在绑定到已启动的服务后从未调用过所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)