在MainActivity中执行数据库操作会冻结UI吗?

时间:2015-08-28 09:14:27

标签: android user-interface android-asynctask android-sqlite

我正在开发一款应用程序来跟踪车辆并计算他们行驶的距离。我有一个安装在车辆上的设备,通过短信将LatLngs发送到我的手机。我的应用会在LatLng中存储包含SQLiteDatabase的短信。我的表每行有一个纬度和经度。我的表中的行数日复一日地变大。 当我从表中检索那些数据以绘制地图和计算距离时,我的应用程序每次尝试从表中访问数据时都会冻结一秒钟。如何让它更快?请提出任何建议。

    public void calculateDistance(String date) {
    googleMap.clear();
    double cumulativeDistance = 0;
    String selectLog1="select rowid _id,* from logTable where date='"+date+"' and deviceNo='"+deviceNo+"'";
    Cursor cursor4=db.rawQuery(selectLog1,null);
    if(cursor4.getCount()>2) {
        while (cursor4.moveToNext()) {
            String strLatLng = cursor4.getString(cursor4.getColumnIndex("log"));
            strDate11=cursor4.getString(cursor4.getColumnIndex("date"));
            String[] strArray = strLatLng.split(",");
            latitude2 = Double.parseDouble(strArray[0]);
            longitude2 = Double.parseDouble(strArray[1]);
            time11=strArray[2];
            coordList1.add(new LatLng(latitude2, longitude2));
            timeList.add(strLatLng+","+time11);
        }

        BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.ledorange);
        for (String strData:timeList){
            String[] strDatas=strData.split(",");
            double latData=Double.parseDouble(strDatas[0]);
            double lngData=Double.parseDouble(strDatas[1]);
            String timeAt=strDatas[2];
            googleMap.addMarker(new MarkerOptions().position(new LatLng(latData,lngData)).title(vehicleName).icon(bitmapDescriptor).snippet("Known @ " + timeAt + "," + strDate11));
        }

        timeList.removeAll(timeList);

        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(latitude2, longitude2), 12.5f);
        googleMap.animateCamera(cameraUpdate);
        googleMap.addPolyline(new PolylineOptions().addAll(coordList1).width(10).color(getResources().getColor(R.color.myBlue)));

        DecimalFormat format = null;
        for (int i = 0; i < (coordList1.size() - 1); i++) {
            LatLng l1 = coordList1.get(i);
            double lat1 = l1.latitude;
            double lng1 = l1.longitude;
            Location location1 = new Location("");
            location1.setLatitude(lat1);
            location1.setLongitude(lng1);

            LatLng l2 = coordList1.get(i + 1);
            double lat2 = l2.latitude;
            double lng2 = l2.longitude;
            Location location2 = new Location("");
            location2.setLatitude(lat2);
            location2.setLongitude(lng2);

            format = new DecimalFormat("#.##");
            double distance = location1.distanceTo(location2) / 1000;
            cumulativeDistance = cumulativeDistance + distance;
        }
        if (preferences.contains("errorRatio")) {
            cumulativeDistance =cumulativeDistance + (cumulativeDistance / 100) * preferences.getInt("errorRatio", 0);
        }
        tvDistance.setText(format.format(cumulativeDistance) + " Km's");
        coordList1.removeAll(coordList1);
    }else {
        tvDistance.setText("No Data");
    }
}

2 个答案:

答案 0 :(得分:0)

如果你的查询非常庞大,它可能会冻结你的主线程。

如果我是你,我会使用AsyncTask进行读/写操作,因为这会发生在另一个线程上而不会冻结你的主线程。

答案 1 :(得分:0)

数据库操作在UI线程上运行,除非您另有说明。您可以使用AsyncTask在后台线程中运行,如下所示:

private class MyLongTask extends AsyncTask<Void, Void, Void> {
     protected void doInBackground(Void... params) {

         // TODO Perform database operations

         return null;
     }

     protected void onPostExecute(Void... params) {
         // TODO update UI with db results
     }
 }

您还可以使用StrictMode检测主线程上的网络/ IO,并通过日志消息或异常通知您。