dimanche 29 novembre 2015

Populate database from network before other code runs

My app has a SQlite database that I am trying to populate at initial install from a server. I am using volley to connect and have a web service on the server side. My issue is that on the first install when I call the method to populate the database it is obviously running on a different thread so before finishing it is moving on the building the UI. The UI is populated from the database so because the database has not been fulling populated I get error.

I have tried to force the volley call to run synchronously but just get a timeout exception

11-29 09:38:49.646 4206-4206/com.clashtoolkit.clashtoolkit W/System.err: java.util.concurrent.TimeoutException
11-29 09:38:49.646 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.android.volley.toolbox.RequestFuture.doGet(RequestFuture.java:121)
11-29 09:38:49.646 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.android.volley.toolbox.RequestFuture.get(RequestFuture.java:97)
11-29 09:38:49.646 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.clashtoolkit.clashtoolkit.network.ArmyNetworking.getTableFromServer(ArmyNetworking.java:93)
11-29 09:38:49.646 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.clashtoolkit.clashtoolkit.database.DataCreator.getDatabaseFromServer(DataCreator.java:1657)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.clashtoolkit.clashtoolkit.UI.ArmyBuilder.onCreate(ArmyBuilder.java:46)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.Activity.performCreate(Activity.java:5990)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.ActivityThread.access$800(ActivityThread.java:151)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-29 09:38:49.647 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.os.Looper.loop(Looper.java:135)
11-29 09:38:49.648 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5257)
11-29 09:38:49.648 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
11-29 09:38:49.648 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
11-29 09:38:49.648 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
11-29 09:38:49.648 4206-4206/com.clashtoolkit.clashtoolkit W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

I cannot figure out the best way to do this. The DB has to be populated first, but I cannot seem to stop the UI code from running before it has been populated.

Main.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_army_builder);

    //create and populate the database
    DataCreator dbCreate = new DataCreator();
    dbCreate.getDatabaseFromServer(this);




        //creates the Toolbar and setting it as the Toolbar for the activity
        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);

        // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
        adapter = new TroopPagerAdapter(getSupportFragmentManager(), titles, numberOfTabs);

        //Assigning ViewPager View and setting the adapter
        pager = (ViewPager) findViewById(R.id.army_pager);
        pager.setOffscreenPageLimit(4);
        pager.setAdapter(adapter);

        //assigning the sliding tab layout view
        tabs = (SlidingTabLayout) findViewById(R.id.army_tabs);
        //creating the icon portion of the sliding tabs
        tabs.setCustomTabView(R.layout.custom_tabs, R.id.tabText);

        //Setting custom color for the Scroll bar indicator of the Tab View
        tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position) {
                return getResources().getColor(R.color.ColorPrimaryDark);
            }
        });

        //Setting the ViewPager for the slidingtabsLayout
        tabs.setViewPager(pager);

        //Set the barracks fragments to the barracks viewpager
        BuilderObjData builderObjData = new BuilderObjData();
        ArrayList<Builder> barracksArray = builderObjData.getBuilderObjArray(this, Utilities.BUILDER_TYPE_BARRACKS);
        bAdpter = new BarracksPagerAdapter(getSupportFragmentManager(), barracksArray);

        bPager = (ViewPager) findViewById(R.id.barracks_pager);
        bPager.setAdapter(bAdpter);
}

getDatabaseFromServer()

 public void getDatabaseFromServer(Context context) {

    Cursor cursor = context.getContentResolver().query(Container.CONTENT_URI, null, null, null, null);

    if (cursor == null || cursor.getCount() == 0) {
        for (String table : DataCreator.TABLES) {
            ArmyNetworking.getTableFromServer(table, context);
        }
        if (cursor != null) {
            cursor.close();
        }
    }
}

getTableFromServer()

 public static void getTableFromServer(final String tableName, final Context context) {
    Log.d(TAG, "called now");
    String url = ArmyNetworking.WEB_BASE_URL + ArmyNetworking.PATH_TABLE + "/" + tableName;

//        RequestFuture<JSONArray> future = RequestFuture.newFuture();
//        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, future, future);

    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
            url,
            (String) null,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    updateTableFromServer(response, context, tableName);
                    Log.d(TAG, "got response");
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            //add error handling
        }
    });

    VolleySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);

//        try {
//            JSONArray response = future.get(30, TimeUnit.SECONDS);
//            updateTableFromServer(response, context, tableName);
//
//        } catch (InterruptedException | ExecutionException | TimeoutException e) {
//            e.printStackTrace();
//        }
}

The above method shows the two different ways I tried to make the Volley call. The commented out code is to force it to be synchronous

Aucun commentaire:

Enregistrer un commentaire