Мне нужно загрузить некоторые данные, как только пользователь войдет в приложение.Я поставил - сетевые вызовы для загрузки этих данных и - транзакции базы данных, чтобы записать их в sqlite
в службе намерений.Данные огромны, поэтому их сохранение в sqlite занимает много времени.Но мне интересно, почему служба намерений блокирует пользовательский интерфейс.Я не могу перемещаться по приложению.Если я нажимаю на любую кнопку, ничего не происходит.Если я нажимаю снова, приложение просто зависает и в конечном итоге вызывает ANR.
Я использовал Сервис ранее.Поскольку служба работает в основном потоке, я использую IntentService.У меня были одновременные AsyncTasks для загрузки каждого набора данных.Теперь я избавился от этих AsyncTasks и обработал все сетевые вызовы в методе onHandleIntent.Я тестирую на устройстве Android версии 5.1.1 (леденец).
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