使用存储库在本地数据库/位置和网络之间同步

时间:2018-03-24 22:11:39

标签: java android android-fragments android-room android-architecture-components

我正在实施一个天气应用程序,它通过Retrofit和来自GoogleFusedLocationClient的位置从DarkSky获取预测。我的目标是通过应用程序关闭和配置更改来保存UI数据。我使用Room + ViewModel + LiveData和Repository模型实现了它。但是我在我的片段而不是存储库中获取我的位置和预测,目标是将其移动到存储库 这样存储库就会查看数据库,如果它是空的,则从网络中获取数据 我目前的存储库:

public class UIRepository {

    private UIDao mUIDao;
    private LiveData<List<UIData>> mAllUIData;

    UIRepository(Application application) {
        PhotoDatabase db = PhotoDatabase.getDatabase(application);
        mUIDao = db.uiDao();
        mAllUIData = mUIDao.getAllUIData();
    }

    LiveData<List<UIData>> getAllUIData() {
        return mAllUIData;
    }

    public void insert(UIData uiData) {
        new insertAsyncTask(mUIDao).execute(uiData);
    }

    private static class insertAsyncTask extends AsyncTask<UIData, Void, Void> {

        private UIDao mAsyncDao;

        insertAsyncTask(UIDao uiDao) {
            mAsyncDao = uiDao;
        }

        @Override
        protected Void doInBackground(UIData... uiData) {
            mAsyncDao.insert(uiData[0]);
            return null;
        }
    }
} 

我可以找到获取位置的单独课程here。而对于预测,它只是改造 我将如何在存储库中组合这些元素?

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。基本上你想在public class PhotoActivity extends Activity { ImageView vitb; Button btcm, btdn; static final int REQUEST_IMAGE_CAPTURE = 1; static final int REQUEST_IMAGE_SELECT = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_photo); vitb = findViewById(R.id.imageView); btcm = findViewById(R.id.btn_cam); btdn = findViewById(R.id.btn_back); btcm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectImage(); } }); btdn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Drawable drawable = vitb.getDrawable(); Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap(); ByteArrayOutputStream bs = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 0, bs); byte[] byteArray = bs.toByteArray(); Intent nIntent = new Intent(); nIntent.putExtra("PICTURE", byteArray); setResult(RESULT_OK, nIntent); finish(); } }); } private void selectImage() { final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" }; AlertDialog.Builder builder = new AlertDialog.Builder(PhotoActivity.this); builder.setTitle("Add Photo!"); builder.setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { if (options[item].equals("Take Photo")) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent,REQUEST_IMAGE_CAPTURE); } else if (options[item].equals("Choose from Gallery")) { Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent,REQUEST_IMAGE_SELECT); } else if (options[item].equals("Cancel")) { dialog.dismiss(); } } }); builder.show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == 1) { Bitmap bmp; Bundle bundle = data.getExtras(); bmp = (Bitmap)bundle.get("data"); vitb.setImageBitmap(bmp); } else if (requestCode == 2) { Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); //ImageView imageView = findViewById(R.id.imageView); vitb.setImageBitmap(BitmapFactory.decodeFile(picturePath)); } } } } 中编写逻辑,决定是否从服务器或本地数据库中获取数据。 幸运的是,这是一个非常常见的问题,因此Google提出了NetworkBoundResource类。

public class MainActivity extends Activity{ private static final int REQUEST_CODE1 = 101; private static final int REQUEST_CODE2 = 102; Button btnLoc, btnPic; Button btnSubmit; TextView tvLoc; ImageView image; String phoneNumber = "9000000000"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnSubmit = findViewById(R.id.btnSubmit); btnLoc = findViewById(R.id.btnLoc); btnPic = findViewById(R.id.btnPic); tvLoc = findViewById(R.id.textView3); image = findViewById(R.id.img); btnSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { SmsManager.getDefault().sendTextMessage(phoneNumber, null, "Hello!", null, null); } catch (Exception e) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this); AlertDialog dialog = alertDialogBuilder.create(); dialog.setMessage(e.getMessage()); dialog.show(); } } }); btnLoc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this,LocActivity.class); startActivityForResult(intent,REQUEST_CODE1); } } ); btnPic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this,PhotoActivity.class); startActivityForResult(intent,REQUEST_CODE2); } }); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK){ if(requestCode == REQUEST_CODE1 && data !=null) { String strMessage = data.getStringExtra("loc"); tvLoc.setText(strMessage); } if(requestCode == REQUEST_CODE2 && data !=null) { Bundle extras = getIntent().getExtras(); byte[] b = extras.getByteArray("PICTURE"); Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length); image.setImageBitmap(bmp); } } } } 是一个普通类,它使用Repository的强大功能完成本地数据库和Web服务之间的数据流。

阅读详情:https://proandroiddev.com/building-modern-apps-using-the-android-architecture-guidelines-3238fff96f14

和官方文件:https://developer.android.com/jetpack/docs/guide