What about multithreading in Android SQLite?

前端 未结 6 1068
旧巷少年郎
旧巷少年郎 2021-02-05 16:06

In my app I\'ve got to implement some UI and Sync service. It runs in the background and updates data. Sync service is not very simple, it uses multithreading.

So, here

6条回答
  •  悲哀的现实
    2021-02-05 16:16

    Ciaoo: Here the solution:

    I tried to explain everything in the code .

    import android.app.Activity;
    import android.content.Context;
    import android.database.Cursor;
    import android.os.AsyncTask;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewTreeObserver;
    import android.widget.ScrollView;
    
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    class HelpUI {
    
       final static class GetDataFromDBInAsyncMode extends AsyncTask {
    
          private Context context;
          private String SQL;
          private final int xMin = -X_App.ScreenHeight; // put here your screen height (get it from code)
          private final int xMax = X_App.ScreenHeight * 2; // put here your screen height (get it from code)
    
          // this is the main view witch go to have all views
          // Use this in onProgressUpdate to add other vies you get in runtime when you get data from database
          private ViewGroup view_container;
    
          // if you have a scrollview hide views witch isnot visible to user
          private ScrollView scroll_view_container;
    
          // this workaround make free processors in measureaments, your UI is more fluent
          final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = () -> {
    
             if (view_container == null || view_container.getChildCount() == 0) { return; }
    
             int scrollY = scroll_view_container.getScrollY();
    
             for (int i = 0; i < view_container.getChildCount(); i++) {
    
                final View current = view_container.getChildAt(i);
                final int topView = current.getTop(); //container_views.getChildAt(i).getTop();
                final int diffTop = topView - scrollY;
    
                if ((diffTop > xMin) && (diffTop < xMax)) {
                   current.setVisibility(View.VISIBLE);
                } else {
    
                   current.setVisibility(View.INVISIBLE);
                }
    
             }
    
          };
    
          // constructor
          GetDataFromDBInAsyncMode(Context ctx, String mSQL) {
             this.context = ctx;
             this.SQL = mSQL;
    
             // put here the id of scrollViewContainer
             scroll_view_container = X_App.getRootV().findViewById(R.id.scroll_view_container);
             if (scroll_view_container != null) {
                // add listener on scroll
                scroll_view_container.getViewTreeObserver().addOnScrollChangedListener(onScrollChangedListener);
             }
    
          }
    
    
          @Override
          protected Object doInBackground(Object... objects) {
    
    
             // All dirty things go to being in background
             // Your cursor
             final Cursor cursor = X_SqLite.get(X_App.getContext()).GeDataAsCursor(SQL);
    
             if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) {
    
                // The magic part
                ScheduledExecutorService giveMeAsync = Executors.newSingleThreadScheduledExecutor();
    
                // Give time to processor to do her tasks and do you dirty task here
                // 50 millisec is enough per a single task
                giveMeAsync.scheduleAtFixedRate(() -> {
                   ViewGroup viewInflated = ((Activity) this.context).findViewById(R.id.icon_view);
    
                   // Give your data from Database
                   // Do here all your things but take care some of these need to be done on UI thread (like adding view etc, you can do that on onProgressUpdate)
                   final String data1 = cursor.getString(cursor.getColumnIndex("data1"));
                   viewInflated.setTag(data1);
    
                   // Send this to UI thread
                   publishProgress(viewInflated, false);
    
                   // Here test to cursor if is finish or not
                   if (!cursor.moveToNext()) {
                      giveMeAsync.shutdownNow();
                      cursor.close();
                      publishProgress(null, true);
                   }
    
                }, 1, 50, TimeUnit.MILLISECONDS);
    
    
             }
    
             // otherwise if cursor is emty close them
             if (cursor != null && cursor.getCount() == 0) {
                cursor.close();
                publishProgress(null, true);
             }
    
    
             return null;
    
          }
    
    
          @Override
          protected void onProgressUpdate(Object... values) {
             final View viewInflated = (View) values[0];
             final boolean isCursorEnded = (Boolean) values[0];
    
             // Here you is in main thread
             // You can do all what you do with the viewInflated
    
    
             if (isCursorEnded) {
                //raise your event to tell to your app reading data is finished
             }
    
          }
    
    
       }
    
    
    }
    

    Usage:

    import android.app.Activity;
    import android.os.Bundle;
    
    class MyActivity extends Activity {
       @Override
       protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          new HelpUI.GetDataFromDBInAsyncMode(this, "Select * FROM YourTable").execute();
       }
    } 
    

    Change variables with your variables/objects

提交回复
热议问题