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