我有一个运行良好的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);
}
链接到错误的
QueryDB
是DatabaseConnector
中的一个类。经过大量的Google搜索并关注了SO链接之后,我找到了一个SO答案,建议创建类
QueryDB
static
。这样做摆脱了上面的错误。但是由于将
QueryDB
从AsyncTask
更改为IntentService
是我所做的唯一更改,因此我遇到了另一个错误,我想知道该怎么做,但是我还有很长的路要走,而且我不想将此更改更改为回来咬我。QueryDB
执行并终止后,将在进一步的用户输入后再次执行。只要我只需要随时执行它的一个实例,是否使
QueryDB
类static
完全安全并且是一个好主意?我认为它必须是DatabaseConnector
的内部类。编辑
根据第一个评论中的建议,this将被证明很有趣。
this也可以。
最佳答案
与您直接处理的AsyncTask相反,Service是一个组件,应该由OS注册/索引。因此,您对组件的生命周期有间接影响。如果将IntentService实现为内部类,则它应该是静态的,否则Android系统将无法启动该服务。另外,正确的注册看起来像<service android:name=".MyEnclosedClass$MyIntentService" />
至于静态类的安全性(通常),内存泄漏可能是一个问题。引用静态对象时应小心,因为它可能会由于封装对象(EO)而失效(由于配置更改),因此垃圾收集器无法收割EO。