安卓系统打开创建死锁



我在弄清楚如何正确组织特定的android代码时遇到了一些问题。

这是代码的体系结构:在活动的onCreate中,addService通过bindService完成一些工作,只有在onServiceConnected方法成功完成后才能运行getServices:

public class MyClass{
    List<IBinder> binders = new ArrayList<IBinder>;
    int stillSettingUp = 0;
    public void addService(Class<?> cls) {
        //Adds a binder via bindService 
        ServiceConnection mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName className, IBinder service) {
                //Callback for service being successfully started
                binders.add(service);
                stillSettingUp--;
            }
        };
        //Increment count of the number of services being set up
        stillSettingUp++;
        Intent intent = new Intent(context, cls);
        context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
    public List<IBinder> getServices(){
        while (stillSettingUp != 0) {
            Log.w("", "Waiting for services to successfully connect... " + stillSettingUp);
            Thread.sleep(1000);
        }
        return binders;
    }
}

问题是:第二种方法需要完成onServiceConnected函数。在整个onCreate函数完成之前,onServiceConnected函数无法执行(因为它们是附加到主循环末尾的事件,在当前事件完成之前无法执行),因此系统死锁。

有没有一种方法可以强制UI线程上的其他事件进行处理,或者有更好的方法来编排代码?我试图避免每次同时调用这两段代码时都运行AsyncTask,因为这需要向调用代码公开线程需求。然而,这很困难,因为不能强制服务连接回调在它们自己的线程中执行。欢迎提出任何建议。

看起来您需要的是在第一个和第二个函数都完成后立即在UI线程上执行第三个函数。那么,为什么不使用AsyncTask并将第一个和第二个例程放在doInBackground()中,同时将第三个例程放置在onPostExecute() 中呢?

以下是我的问题:

1) 如果你必须依赖于来自Android回调的数据,你不应该阻止,因为Android回调不会像其他编程模式那样发布到单独的线程。相反,您应该优雅地越过需要数据的点,可能会在例如轮询线程中重新尝试数据访问。

2) 您还可以传入一个可运行的,以便在连接服务后执行。然而,这可能会变得非常混乱。

3) 不要使用太多服务。通常,只使用一个或两个服务要比使用一堆相互通信的服务容易得多。我重写了这组代码,现在我不再经常处理绑定服务,它的可维护性提高了20倍。

最新更新