Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

將App從背景移除時,會發生錯誤 #113

Closed
ArthurPai opened this issue Apr 16, 2016 · 6 comments
Closed

將App從背景移除時,會發生錯誤 #113

ArthurPai opened this issue Apr 16, 2016 · 6 comments
Labels

Comments

@ArthurPai
Copy link

ArthurPai commented Apr 16, 2016

我現在做一個Unity3D的檔案背景下載的Plugin,底層使用這個Library來做
最後會輸出成一個jar檔讓Unity3D載入

現在已經可以正常add/pause檔案下載
目前遇到一個問題,當App進入背景後,我再手動將App從背景移除,
會發生下面的錯誤訊息
Android的畫面上也會跳出 "很抱歉,程式已停止" 的Error Dialog

看Log Trace感覺像是Service跟著App一起被移除,然後又被自動重新啟動(START_STICKY)
這時好像Application Context是null,結果跳出NullPointerException
請問一下,這邊該如何處理?

java.lang.RuntimeException: Unable to create service com.liulishuo.filedownloader.services.FileDownloadService: java.lang.NullPointerException
   at android.app.ActivityThread.handleCreateService(ActivityThread.java:2733)
   at android.app.ActivityThread.access$1800(ActivityThread.java:139)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:149)
   at android.app.ActivityThread.main(ActivityThread.java:5257)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:817)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
   at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
   at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
   at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
   at com.liulishuo.filedownloader.services.FileDownloadDBHelper.<init>(FileDownloadDBHelper.java:52)
   at com.liulishuo.filedownloader.services.FileDownloadMgr.<init>(FileDownloadMgr.java:53)
   at com.liulishuo.filedownloader.services.FileDownloadService$FileDownloadServiceBinder.<init>(FileDownloadService.java:88)
   at com.liulishuo.filedownloader.services.FileDownloadService$FileDownloadServiceBinder.<init>(FileDownloadService.java:82)
   at com.liulishuo.filedownloader.services.FileDownloadService.createBinder(FileDownloadService.java:64)
   at com.liulishuo.filedownloader.services.FileDownloadService.createBinder(FileDownloadService.java:41)
   at com.liulishuo.filedownloader.services.BaseFileService.onCreate(BaseFileService.java:70)
   at com.liulishuo.filedownloader.services.FileDownloadService.onCreate(FileDownloadService.java:49)
   at android.app.ActivityThread.handleCreateService(ActivityThread.java:2723)
   at android.app.ActivityThread.access$1800(ActivityThread.java:139) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:149) 
   at android.app.ActivityThread.main(ActivityThread.java:5257) 
   at java.lang.reflect.Method.invokeNative(Native Method) 
   at java.lang.reflect.Method.invoke(Method.java:515) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:817) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633) 
   at dalvik.system.NativeStart.main(Native Method) 
@ArthurPai
Copy link
Author

這是我的AndroidManifest.xml檔案

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.intxtion.downloader"
    android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="18" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="18" />

    <supports-screens android:anyDensity="true" android:largeScreens="true"
        android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />

    <application android:debuggable="true"
        android:icon="@drawable/app_icon" android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
        <activity
            android:name="com.intxtion.downloader.IntxtionActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
        <service android:enabled="true" android:name="com.liulishuo.filedownloader.services.FileDownloadService" />
    </application>
</manifest>

@Jacksgong
Copy link
Collaborator

@ArthurPai 你已经找到原因,那么就在 Application#onCreate 的 是否执行下 FileDownloader.init(Application):void.

P.S: 只要下载进程启动就会执行你绑定的 Application 的生命周期。

@ArthurPai
Copy link
Author

ArthurPai commented Apr 16, 2016

@Jacksgong
目前我的程式是在Main Activity中執行FileDownloader.init(application_context)。

我的疑惑是當主線程被kill掉以後,那麼Service重新啟動時,
這時候,重新啟動的Process應該不是原本的主程式(已被kill掉)
這個時候要從哪邊獲取到Application Context呢?
這時候會是誰呼叫FileDownloader.init()並傳入context?
如果沒有人呼叫的話,那麼FileDownloadHelper.APP_CONTEXT將會是null

@Jacksgong
Copy link
Collaborator

Android中,每个进程都有自己的 Application 对象。下载进程启动的时候,会调用下载进程的 Application 的生命周期。并不是只有你的主进程会调用 Application。因此,只要你在 AndroidManifest 中指定 Application(如 DemoApplication) ,那么 Application#onCreate 就会在每个进程启动的时候被调用,对于你提到的问题,会在下载进程重启的时候调用下载进程 Application#onCreate 的时候传入。

@ArthurPai
Copy link
Author

@Jacksgong
意思是不是一定要將init()放在Application#onCreate中,
這樣下載進程在重新啟動時,就會使用Application#onCreate而執行到其中的init()片段?

我剛剛測試將init()從MainActivity#onCreate移到Application#onCreate就解決了。

感謝,從你這裡學到好多~~~^^

@Jacksgong
Copy link
Collaborator

@ArthurPai 是的。OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants