Максимальная длина метода Intent putExtra? (Принудительное закрытие)
Мне нужна помощь в отладке моего приложения. Прежде всего: в эмуляторе и на некоторых других устройствах мое приложение работает нормально. На моем устройстве я получил принудительное закрытие (без сообщения о принудительном закрытии).
"Сбой" происходит, если активность приложения изменяется.
Вот некоторый код класса MainActivity
. Он просто считывает содержимое html с веб-страницы через webview. И нет, это НЕВОЗМОЖНО сделать заново HttpRequest
потому что я не смог смоделировать запрос post.
public class MainActivity extends Activity {
public final static String EXTRA_HTML = "com.example.com.test.HTML";
private WebView mWebView;
private ProgressDialog mDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webView1);
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
mWebView.setBackgroundColor(0);
mWebView.setWebChromeClient(new WebChromeClient() {
public boolean onConsoleMessage(ConsoleMessage cmsg) {
if (cmsg.message().startsWith("MAGIC")) {
mDialog.cancel();
/*HashMap<String, String> message = new HashMap<String, String>();*/
String msg = cmsg.message().substring(5);
Intent intent = new Intent(MainActivity.this,
ReadDataActivity.class);
/*message.put("message", msg);*/
/*intent.putExtra(EXTRA_HTML, message);*/
intent.putExtra(EXTRA_HTML, msg);
startActivity(intent);
}
return false;
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setPluginState(PluginState.OFF);
mWebView.getSettings().setLoadsImagesAutomatically(false);
mWebView.getSettings().setBlockNetworkImage(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setSavePassword(true);
mWebView.getSettings()
.setCacheMode(WebSettings.LOAD_NORMAL);
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String address) {
if (address.indexOf("mySession") != -1) {
view.loadUrl("javascript:console.log('MAGIC'+document.getElementsByTagName('html')[0].innerHTML);");
}
});
mWebView.loadUrl("http://www.myurl.de");
}
Итак, в onConsoleMessage()
методе я просто передаю html-код другому классу Activity, который считывает, анализирует и отображает содержимое.
Проблема теперь в том, что на этом этапе, когда ReadDataActivity
класс должен быть загружен, приложение просто закрывается и возвращается на главный экран без какого-либо сообщения или пользовательского диалога.
Возможно ли, что html-код, который передается в виде строки в ReadDataActivity
, слишком большой? Я также пытаюсь добавить html-код в виде строки в HashMap, но проблема та же.
Есть идеи, что я могу сделать для устранения проблемы? Может быть, мне стоит попробовать создать Parcelable
объект?
В эмуляторе все работает нормально.
Переведено автоматически
Ответ 1
Согласно моему опыту (некоторое время назад), вы можете размещать до 1 МБ данных в Bundle
для IPC. Это ограничение может быть уменьшено, если в данный момент времени происходит много транзакций. Дополнительная информация здесь.
Чтобы решить эту проблему, я бы посоветовал вам сохранить содержимое во временном файле и передать путь / URI вашего временного файла для вашего второго действия. Затем в вашем втором действии прочитайте содержимое файла, выполните нужные операции и, наконец, удалите этот файл.
Если вы хотите, вы также можете включить Shared_Preferences для этой задачи - если вы считаете, что обработка файлов громоздка.
Ответ 2
Я провел небольшое исследование максимального объема данных, который вы можете передавать с помощью Intent. И кажется, что ограничение не приближается к 1 МБ или 90 КБ, оно больше похоже на 500 КБ (протестировано в API 10, 16, 19 и 23).
Я написал сообщение в блоге на эту тему, вы можете найти его здесь: http://web.archive.org/web/20200217153215/http://neotechsoftware.com/blog/android-intent-size-limit
Ответ 3
Ограничение размера Intent в Jelly Bean по-прежнему довольно низкое, оно несколько ниже 1 МБ (около 90 КБ), поэтому вам всегда следует быть осторожным с длиной данных, даже если ваше приложение нацелено только на последние версии Android.
Ответ 4
Я видел, что запись и чтение из файла приводит к снижению производительности. Затем я увидел это решение : . Итак, я использую это решение :
public class ExtendedDataHolder {
private static ExtendedDataHolder ourInstance = new ExtendedDataHolder();
private final Map<String, Object> extras = new HashMap<>();
private ExtendedDataHolder() {
}
public static ExtendedDataHolder getInstance() {
return ourInstance;
}
public void putExtra(String name, Object object) {
extras.put(name, object);
}
public Object getExtra(String name) {
return extras.get(name);
}
public boolean hasExtra(String name) {
return extras.containsKey(name);
}
public void clear() {
extras.clear();
}
}
Затем в MainActivity я вызвал его следующим образом :
ExtendedDataHolder extras = ExtendedDataHolder.getInstance();
extras.putExtra("extra", new byte[1024 * 1024]);
extras.putExtra("other", "hello world");
startActivity(new Intent(MainActivity.this, DetailActivity.class));
и подробнее об активности
ExtendedDataHolder extras = ExtendedDataHolder.getInstance();
if (extras.hasExtra("other")) {
String other = (String) extras.getExtra("other");
}