我有一个运行良好的Android应用程序,但我希望它能够在后台运行,即使没有焦点也可以继续运行。
QueryDB(请参见下文)在应用程序的当前版本中扩展了AsyncTask。建议我使用Service(或IntentSerivce)完成上述目标。

因此,我更改了QueryDB以将IntentService扩展为初学者。

这样做在Android Studio 1.5.1中导致此异常:

04-29 12:02:45.544 1523-1523/com.dslomer64.wordyhelperton E/AndroidRuntime:
FATAL EXCEPTION: main

    Process: com.dslomer64.wordyhelperton, PID: 1523

    java.lang.RuntimeException: Unable to instantiate service
    com.dslomer64.wordyhelperton.DatabaseConnector$QueryDB:
                                                   ^^^^^^^
    java.lang.InstantiationException:
    java.lang.Class<com.dslomer64.wordyhelperton.DatabaseConnector$QueryDB>
    has no zero argument constructor

            at android.app.ActivityThread.handleCreateService(ActivityThread.java:2880)
            at android.app.ActivityThread.access$1900(ActivityThread.java:157)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1439)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5551)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)


 Caused by: java.lang.InstantiationException:
 java.lang.Class<com.dslomer64.wordyhelperton.DatabaseConnector$QueryDB>
                                                                ^^^^^^^
     has no zero argument constructor


            at java.lang.Class.newInstance(Native Method)
            at android.app.ActivityThread.handleCreateService(ActivityThread.java:2877)
            at android.app.ActivityThread.access$1900(ActivityThread.java:157) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1439) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:148) 
            at android.app.ActivityThread.main(ActivityThread.java:5551) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 

这是导致错误的QueryDB的开始:
 public class QueryDB extends IntentService
  {
    public QueryDB()
    {
      super("QueryDB");
    }

    public QueryDB(String name)
    {
      super(name);
    }

链接到错误的QueryDBDatabaseConnector中的一个类。

经过大量的Google搜索并关注了SO链接之后,我找到了一个SO答案,建议创建类QueryDB static。这样做摆脱了上面的错误。

但是由于将QueryDBAsyncTask更改为IntentService是我所做的唯一更改,因此我遇到了另一个错误,我想知道该怎么做,但是我还有很长的路要走,而且我不想将此更改更改为回来咬我。
QueryDB执行并终止后,将在进一步的用户输入后再次执行。

只要我只需要随时执行它的一个实例,是否使QueryDBstatic完全安全并且是一个好主意?我认为它必须是DatabaseConnector的内部类。

编辑

根据第一个评论中的建议,this将被证明很有趣。

this也可以。

最佳答案

与您直接处理的AsyncTask相反,Service是一个组件,应该由OS注册/索引。因此,您对组件的生命周期有间接影响。如果将IntentService实现为内部类,则它应该是静态的,否则Android系统将无法启动该服务。另外,正确的注册看起来像
<service android:name=".MyEnclosedClass$MyIntentService" />
至于静态类的安全性(通常),内存泄漏可能是一个问题。引用静态对象时应小心,因为它可能会由于封装对象(EO)而失效(由于配置更改),因此垃圾收集器无法收割EO。

10-04 20:03