意向服务阻止UI并导致ANR

时间:2019-07-03 13:35:04

标签: android performance android-sqlite android-intentservice android-anr-dialog

用户登录应用后,我必须立即下载一些数据。我把 -网络调用下载此数据,并 -数据库事务将其写入sqlite

在意向服务中

。数据非常庞大,因此将其保存到sqlite需要花费时间。但是我想知道为什么意图服务阻止了UI。我无法浏览该应用程序。如果我单击任何按钮,则什么都不会发生。如果我再次单击,应用程序将冻结并最终导致ANR。

我以前使用过Service。由于服务在主线程上运行,因此我正在使用IntentService。我有并发的AsyncTasks用于下载每组数据。现在,我摆脱了那些AsyncTasks并在onHandleIntent方法中处理了所有网络调用。我正在5.1.1(lollipop)版本的Android设备上进行测试。

public class MastersSyncService extends IntentService {
private static final String TAG = "MastersSyncService";
private static final int CUSTOMERS_PAGE_LENGTH = 5000;

private Context mContext;
private DataSource dataSource;
private boolean isReset;
private ProgressDialog pDialog;
private int numOfCustReceived, pageNumber, customersVersion;
private AlertDialog alertDialog;

public MastersSyncService() {
    super(TAG);
}

@Override
protected void onHandleIntent(Intent intent) {
    mContext = MastersSyncService.this;
    dataSource = new DataSource(mContext);

    if (intent.getExtras() != null) {
        isReset = intent.getBooleanExtra("isReset", false);
    }
    customersVersion = dataSource.customers.getVersion();
    if (customersVersion == 0) {
        dataSource.customers.truncateTable();
    }

    downloadPackingDataMasters();
    downloadCommoditiesMasters(); //makes a network call and writes some simple data to sqlite
    downloadPaymentTypesMasters(); //makes a network call and writes some simple data to sqlite
    downloadReasonsMasters(); //makes a network call and writes some simple data to sqlite
    downloadMeasurementTypesMasters(); //makes a network call and writes some simple data to sqlite
    downloadDocketsMasters(); //makes a network call and writes some simple data to sqlite
    downloadContractsMasters(); //makes a network call and writes some simple data to sqlite
    downloadBookingModesMasters(); //makes a network call and writes some simple data to sqlite
    downloadPincodeMasters(); //makes a network call and writes some simple data to sqlite
    downloadCustomersMasters(); //this method has a recursive network call with pagination. Takes a lot of time

}

public void downloadCustomersMasters() {
    try {

        Globals.lastErrMsg = "";
        String url = VXUtils.getCustomersUrl(customersVersion, pageNumber);
        Utils.logD("Log 1");

        InputStream inputStream = HttpRequest.getInputStreamFromUrlRaw(url, mContext);
        if (inputStream != null) {
            pageNumber++;
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            dataSource.beginTransaction();
            String line = null;
            while ((line = reader.readLine()) != null) {
                if (Utils.isValidString(line)) {
                    numOfCustReceived++;
                    Utils.logD("line from InputStream: " + line);
                    parseCustomer(line);
                }
            }
            dataSource.endTransaction();
        } else {
            numOfCustReceived = 0;
            Utils.logD(TAG + " InputStream is null");
        }
    } catch (IOException ioe) {
        ioe.printStackTrace();
        System.out.println("Exception while reading input " + ioe);
    } catch (Exception e) {
        e.printStackTrace();
        if (!Utils.isValidString(Globals.lastErrMsg))
            Globals.lastErrMsg = e.toString();
        if (Globals.lastErrMsg.equalsIgnoreCase("null"))
            Globals.lastErrMsg = getString(R.string.server_not_reachable);
    }

    if (numOfCustReceived >= CUSTOMERS_PAGE_LENGTH) {
        downloadCustomersMasters();
    } else {
        if (!Utils.isValidString(Globals.lastErrMsg) && pDialog != null && pDialog.isShowing()) {
            Utils.updateTimeStamp(mContext, Constants.CUSTOMERS_DATE_PREF);
        }
    }
}

public void downloadPackingDataMasters() {
    try {

        Globals.lastErrMsg = "";

        int version = dataSource.packingData.getVersion();
        String url = VXUtils.getPackingDataUrl(version); //, imei, versionCode + ""
        Utils.logD("Log 1");
        PackingDataResponse response = (PackingDataResponse) HttpRequest
                .getInputStreamFromUrl(url, PackingDataResponse.class,
                        mContext);

        if (response != null) {
            Utils.logD("Log 4");
            Utils.logD(response.toString());
            if (response.isStatus()) {
                List<PackingDataModel> data = response.getData();
                if (Utils.isValidArrayList((ArrayList<?>) data)) {
                    if (isReset)
                        dataSource.packingData.truncateTable();
                    int val = dataSource.packingData.savePackingData(data, version);
                }
            } else {
                Globals.lastErrMsg = response.getMessage();
            }
        }

    } catch (Exception e) {
        if (!Utils.isValidString(Globals.lastErrMsg))
            Globals.lastErrMsg = e.toString();
        if (Globals.lastErrMsg.equalsIgnoreCase("null"))
            Globals.lastErrMsg = getString(R.string.server_not_reachable);
    }

    if (!Utils.isValidString(Globals.lastErrMsg)) {
        Utils.updateTimeStamp(mContext, Constants.PACKING_DATE_PREF);
    }

}

private final char DEFAULT_QUOTE_CHARACTER = '"';
private final char DEFAULT_SEPARATOR_CHARACTER = ',';

private void parseCustomer(String line) {

    char quotechar = DEFAULT_QUOTE_CHARACTER;
    char separator = DEFAULT_SEPARATOR_CHARACTER;
    if (line == null) {
        return;
    }

    List<String> tokensOnThisLine = new ArrayList<String>();
    StringBuffer sb = new StringBuffer();
    boolean inQuotes = false;
    for (int i = 0; i < line.length(); i++) {

        char c = line.charAt(i);
        if (c == quotechar) {
            if (inQuotes && line.length() > (i + 1)
                    && line.charAt(i + 1) == quotechar) {
                sb.append(line.charAt(i + 1));
                i++;
            } else {
                inQuotes = !inQuotes;
                if (i > 2 && line.charAt(i - 1) != separator
                        && line.length() > (i + 1)
                        && line.charAt(i + 1) != separator) {
                    sb.append(c);
                }
            }
        } else if (c == separator && !inQuotes) {

            if (Utils.isValidString(sb.toString())) {
                String str = sb.toString().trim();
                tokensOnThisLine.add(str);
            } else {
                tokensOnThisLine.add(sb.toString());
            }
            sb = new StringBuffer();
        } else {
            sb.append(c);
        }
    }

    if (Utils.isValidString(sb.toString())) {
        String str = sb.toString().trim();
        tokensOnThisLine.add(str);
    } else {
        tokensOnThisLine.add(sb.toString());
    }
    int customerId = Integer.parseInt(tokensOnThisLine.get(0));
    String custName = tokensOnThisLine.get(2);
    Utils.logD("CUST: " + customerId + " " + custName);
    dataSource.customers.saveCustomerDirect(
            customerId,
            tokensOnThisLine.get(1),
            custName,
            tokensOnThisLine.get(3),
            tokensOnThisLine.get(4),
            tokensOnThisLine.get(5),
            tokensOnThisLine.get(6),
            tokensOnThisLine.get(7),
            Integer.parseInt(tokensOnThisLine.get(8)),
            Integer.parseInt(tokensOnThisLine.get(9)),
            Integer.parseInt(tokensOnThisLine.get(10)),
            Integer.parseInt(tokensOnThisLine.get(11)),
            Integer.parseInt(tokensOnThisLine.get(12)));
}

下载数据需要几分钟。我不能让用户等待这么长时间。请提出在后台下载数据时如何使用户界面具有交互性。或者,请提出一些方法来快速将大量记录保存到sqlite

0 个答案:

没有答案