0

I'm new in android programming. I'm writing simple application that should execute sql file, in first run. But it seems that this process take couple of seconds so I figure that application should show progressDialog while it will be executing sql file. But when I try to run application, dialog is showing with message "app has stopped ...". Please help me.

@Override
public void onCreate(SQLiteDatabase database)
{
    String CREATE_BIBLE_TABLE = "CREATE TABLE bible (" +
            "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "book INTEGER, " +
            "chapter INTEGER NOT NULL, " +
            "verse INTEGER NOT NULL, " +
            "content TEXT" +
            ")";
    database.execSQL(CREATE_BIBLE_TABLE);

    new FirstLoadAsyncTask(database).execute();
}

public class FirstLoadAsyncTask extends AsyncTask<Void, Void, Void>
{
    private SQLiteDatabase database;
    private ProgressDialog progressDialog;

    public FirstLoadAsyncTask(SQLiteDatabase database)
    {
        this.database = database;
    }

    @Override
    protected void onPreExecute()
    {
        ((Activity) context).runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                progressDialog = ProgressDialog.show(context, "Loading...", "");
            }
        });
    }

    @Override
    protected Void doInBackground(Void... params)
    {
        try
        {
            InputStream inputStream = context.getAssets().open("bible.sql");
            execSqlFile(database, inputStream);
        } catch(IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result)
    {
        progressDialog.dismiss();
    }
} 

Class extends SQLiteOpenHelper.

Edit: Logcat:

01-06 18:27:53.221  14118-14118/pl.several27.Biblia_Warszawska E/Trace﹕ error opening trace file: No such file or directory (2)
01-06 18:27:53.891  14118-14118/pl.several27.Biblia_Warszawska I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081_msm7627a_JB_REL_2.0.3_CL2820657_release_AU (CL2820657)
    Build Date: 01/22/13 Tue
    Local Branch:
    Remote Branch: quic/jb_rel_2.0.3
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 +  NOTHING
01-06 18:27:54.001  14118-14118/pl.several27.Biblia_Warszawska E/copybit﹕ Error opening frame buffer errno=13 (Permission denied)
01-06 18:27:54.001  14118-14118/pl.several27.Biblia_Warszawska W/Adreno200-EGLSUB﹕ <updater_create_surface_state:342>: updater_create_surface_state failed to open copybit, error: -13
01-06 18:27:54.011  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x53be8000 size:1536000 offset:0 fd:61
01-06 18:27:54.021  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x5083a000 size:4096 offset:0 fd:63
01-06 18:27:54.381  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x541fb000 size:1536000 offset:0 fd:66
01-06 18:27:54.381  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x50a50000 size:4096 offset:0 fd:68
01-06 18:27:54.501  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x54472000 size:1536000 offset:0 fd:70
01-06 18:27:54.501  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x50c75000 size:4096 offset:0 fd:72
01-06 18:27:55.001  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x545e9000 size:1536000 offset:0 fd:74
01-06 18:27:55.001  14118-14118/pl.several27.Biblia_Warszawska D/memalloc﹕ ion: Mapped buffer base:0x50d4c000 size:4096 offset:0 fd:76
01-06 18:27:57.231  14118-14118/pl.several27.Biblia_Warszawska D/book choosen﹕ 1
01-06 18:27:57.581  14118-14118/pl.several27.Biblia_Warszawska W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x40ca4540)
01-06 18:27:57.601  14118-14118/pl.several27.Biblia_Warszawska E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{pl.several27.Biblia_Warszawska/pl.several27.Biblia_Warszawska.ChapterActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2355)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
            at android.app.ActivityThread.access$600(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5520)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity
            at pl.several27.Biblia_Warszawska.Database$FirstLoadAsyncTask.onPreExecute(Database.java:58)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
            at android.os.AsyncTask.execute(AsyncTask.java:534)
            at pl.several27.Biblia_Warszawska.Database.onCreate(Database.java:42)
            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
            at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
            at pl.several27.Biblia_Warszawska.Database.countChapters(Database.java:148)
            at pl.several27.Biblia_Warszawska.ChapterActivity.onCreate(ChapterActivity.java:32)
            at android.app.Activity.performCreate(Activity.java:5066)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
            at android.app.ActivityThread.access$600(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:155)
            at android.app.ActivityThread.main(ActivityThread.java:5520)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
            at dalvik.system.NativeStart.main(Native Method)
01-06 18:27:59.511  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ killProcess, pid=14118
01-06 18:27:59.521  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ dalvik.system.VMStack.getThreadStackTrace(Native Method)
01-06 18:27:59.521  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ java.lang.Thread.getStackTrace(Thread.java:599)
01-06 18:27:59.521  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ android.os.Process.killProcess(Process.java:956)
01-06 18:27:59.521  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:108)
01-06 18:27:59.531  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
01-06 18:27:59.531  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
01-06 18:27:59.531  14118-14118/pl.several27.Biblia_Warszawska D/Process﹕ dalvik.system.NativeStart.main(Native Method)

Also I tried this way display progressdialog in non-activity class but it won't work too.

And here is whole application source code but without dialog: https://github.com/several27/BibliaWarszawska_Android

Please can anyone help me?

Community
  • 1
  • 1
  • You need to see the logCat, but I think the problem is because you need to call the `dismiss()` method like you were calling the `show()` method, with a `runOnUiThread` – Renan Bandeira Jan 06 '14 at 17:16
  • onPreExecute() already runs on UI Thread. You don't have to create a Runnable object. Edit : Also, you can pass the context object in constructor of AsyncTask and use it for ProgressDialog. You should post the logcat details for more assistance. – Srikanth R Jan 06 '14 at 17:22
  • `((Activity) context)` does not work since context is not an activity. plus, it is useless, as already explained. – njzk2 Jan 06 '14 at 17:31
  • do u have bible sql in ur asset directory – Sush Jan 06 '14 at 17:31
  • Yes I have bible sql in assets folder. – Maciej Szpakowski Jan 06 '14 at 17:32
  • @njzk2 So how should I show this dialog while application will be executing sql? – Maciej Szpakowski Jan 06 '14 at 17:33

2 Answers2

1

I do something like that on my application but I prefer to do that on background, so the user just don't have access to the screens that depend on my database...

You can try something like that:

public class BackgroundSyncService extends IntentService {

    public static final String NOTIFICATION = "com.example.sync.service";
public static final String RESULT = "result";

    public BackgroundSyncService() {
    super("BackgroundSyncService");
}

    @Override
protected void onHandleIntent(Intent intent) {
    //Do here what you want with your database

    //After all process you just notify your activitys
    Intent intent = new Intent(NOTIFICATION);
    intent.putExtra(RESULT, result);
sendBroadcast(intent);
    }

}

Create a receiver (I use a inner class on my project)

private BroadcastReceiver receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                    //Do what you want here , like enable a section of your app
            }
        }
    };

Then you need to register the service to your activity adding :

registerReceiver(receiver, new IntentFilter(BackgroundSyncService.NOTIFICATION));

Don't forget to unregister the receiver:

@Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

Also don't forget to register your IntentService on the AndroidManifest.xml

<service android:name="com.example.service.BackgroundSyncService" />

EDIT

Also you need to include the call to start your service where you want, I start mine on App instance:

Intent intent = new Intent(this, BackgroundSyncService.class);
startService(intent);

EXPLANATION

First you are creating a service to do what you want, the service can do whatever you want, in your case you will fill a database...

After you have created this service, you will set when you want to start this service (the edit part)...

After that you will register your activity to listen the service thats why we have created the BroadcastReceiver, the BroadcastReceiver will be called when your Service execute the line:

 //After all process you just notify your activitys
    Intent intent = new Intent(NOTIFICATION);
    intent.putExtra(RESULT, result);
    sendBroadcast(intent);
GhostDerfel
  • 1,533
  • 1
  • 11
  • 18
  • I'm quite new as I wrote. Can you please explain me what this code will exactly do? – Maciej Szpakowski Jan 06 '14 at 17:39
  • So I understand that this way whole "execution" will be hidden, and the user will just use application without any dialog? I only want to execute this sql once, after first installation of application, and application can't work without it so, I think app have to show this Dialog. – Maciej Szpakowski Jan 06 '14 at 18:19
  • you can keep showing your ProgressDialog, just set your dialog to appear on the intent service call and be dismissed on the result. The database will never change? Why don't you set the database.db already with the content in your application ? Then you don't need to execute this sql to fill the data – GhostDerfel Jan 06 '14 at 18:28
  • Okay it is good idea, but how can I do it? I have to first create this db file, and I just don't know how can I do it, and where then put it? Do you have any tutorial, or something? – Maciej Szpakowski Jan 06 '14 at 18:34
  • Here you can find how to copy the database on my answer http://stackoverflow.com/a/20955378/3036488 and here how to create the db file http://souptonuts.sourceforge.net/readme_sqlite_tutorial.html – GhostDerfel Jan 06 '14 at 18:41
  • I tried your way. I created db file, from sql in emulator, then I took this file put to assets, and use code above to copy file to database directory(the same that sql query create). And I checked the file is copied successfully, but I don't know why script can't read it, it just stop app and: `android.database.sqlite.SQLiteException: no such table: bible (code 1):`. But the table is there. Can you help me? – Maciej Szpakowski Jan 07 '14 at 16:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44723/discussion-between-ghostderfel-and-maciej-szpakowski) – GhostDerfel Jan 07 '14 at 16:52
0

I guess the better way when the app starts you present the user with a message/ an activity that is not database related or just use the splash screen at the time that it is loading and estimate the time it normally finish loading to be the timer of the splash screen

Nasz Njoka Sr.
  • 1,138
  • 16
  • 27