2016-04-29 72 views
2

我有一個可以正常工作的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之內。

經過相當多的谷歌搜索和跟隨SO鏈接後,我發現了一個SO答案,建議創建類QueryDBstatic。這樣做擺脫了上述錯誤。

但由於從AsyncTask改變QueryDBIntentService是我所做的唯一的變化,我得到另一個錯誤,我想我知道該怎麼做,但我有一個很長的路要走,我不想要這個改變回來並咬我。

QueryDB執行並終止後,將在用戶進一步輸入後再次執行。

製作課程QueryDBstatic只要我只需要在任何時候執行它的一個實例,就完全安全並且是個好主意?我認爲它必須是DatabaseConnector的內部類。

編輯

每建議中的第一個評論,this將被證明是有趣的閱讀。

所以可能this

+1

也許你應該閱讀並理解靜態嵌套類與非靜態嵌套類(又名內部類)是什麼。請參閱https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html。那麼你可以自己回答關於「安全」的問題,因爲答案是「取決於」。 – Andreas

回答

1

與您直接處理的AsyncTask相反,Service是一個組件,它應該由OS註冊/索引。所以你對組件的生命週期有間接的影響。如果IntentService作爲內部類實現,它應該是靜態的,否則Android系統將無法啓動該服務。另外一個適當的註冊看起來像

<service android:name=".MyEnclosedClass$MyIntentService" />

至於與靜態類安全(一般)一個內存泄漏可能是一個問題。在給靜態對象引用時應該小心,因爲它可能會超出(由於配置更改)封閉對象(EO),所以垃圾收集器無法收穫EO。

相關問題