2

新しい仕事を始めたばかりで、アプリケーションに大きなデータセットを渡す必要があるアプリを開発しています。現在のところ、アプリケーションは永続ストレージを使用しており、SQLデータベースに絶えず問い合わせして、これらの大きなデータセットをフェッチしてユーザーに表示しています。これらの高価な操作のすべてのため、アプリケーションはほとんど使用できなくなりました(時間がかかりすぎる操作のためのローディングスピナーが多すぎます)。私の解決策は、メインアクティビティが開始されたときにデータをロードし、必要に応じて新しいアクティビティにデータを渡すことです。大量のデータをインテントで渡すとクラッシュする - エクストラバンドルにサイズ制限がありますか?

この変更の最初の段階を1つのデータセットで実装しました。私はUsing Crop intent Getting java.lang.SecurityException: Unable to find app for caller [email protected]だけでなく、小さなデータセットでのテスト:このstackoverflowの記事に基づいて、

04-27 06:42:32.022: E/AndroidRuntime(14180): FATAL EXCEPTION: main 
04-27 06:42:32.022: E/AndroidRuntime(14180): Process: com.myprocess, PID: 14180 
04-27 06:42:32.022: E/AndroidRuntime(14180): java.lang.SecurityException: Unable to find app for caller [email protected] (pid=14180) when publishing content providers 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.os.Parcel.readException(Parcel.java:1472) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.os.Parcel.readException(Parcel.java:1426) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.app.ActivityManagerProxy.publishContentProviders(ActivityManagerNative.java:2977) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.app.ActivityThread.installContentProviders(ActivityThread.java:4591) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4522) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.app.ActivityThread.access$1500(ActivityThread.java:151) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1381) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.os.Handler.dispatchMessage(Handler.java:110) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.os.Looper.loop(Looper.java:193) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at android.app.ActivityThread.main(ActivityThread.java:5292) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at java.lang.reflect.Method.invokeNative(Native Method) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at java.lang.reflect.Method.invoke(Method.java:515) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) 
04-27 06:42:32.022: E/AndroidRuntime(14180): at dalvik.system.NativeStart.main(Native Method) 

:私は意思のエキストラにこのすべてのデータとのArrayListを渡そうとしましたしかし、私は次のエラーを得たのバンドル(ほとんど確実に)インテント・エクストラ・バンドルを介してあまりにも多くのデータを送ることによって引き起こされていることがわかりました。

私には2つの質問があります。

  1. まず、私の評価は正しいですか?私は、余分なバンドルにサイズ制限があることを明示している過去4年間のものは見つけられませんでした(ただし、2012年以降でもたくさんあります)。
  2. 私が正しいと仮定して、私は意図として渡すには大きすぎるデータセットを格納するためにシングルトンを使用し、アクティビティライフサイクルで動作するように必要なチェックを実装することを計画していますアクティビティが破壊され、データが失われた場合はデータベースからロードします)。その他の提案はありますか?私はこれがベストプラクティスではないことを知っていますが、もっと良い方法を考えることはできません。

私も理由はインクリメンタルにデータをロードするアプリケーションのためのユーザビリティ要件のオプションではないことを言及する必要があります。

+0

あなたのログには、すでにのContentProvider、このような名前であることを、意味するかもしれない、とあなたは1以上を登録することはできません、またはあなたのプロバイダとのものがあります。ただし、アクセス・コンテンツのアクセス権が不足している可能性があります –

+0

ArrayListの受け渡しにはパーセル対応の実装が必要です – Haroon

+0

私が追加したコードは、最初のアクティビティでAsyncTaskLoaderを使用してデータベースからデータをロードし、意図。私は間違いなくコンテンツプロバイダーと何もしていません。私の推測では、ログは、Androidシステムがその中にデータを持つインテントを持つアクティビティを起動するために使用するものを指しているということです。 –

答えて

5

はい、制限はありますが、それがどれほど大きいか小さいかは十分に文書化されていません。

参照:Max size of string data that can be passed in intents

いくつかは、あなたがテントエキストラに90キロバイトよりも大きな何かを渡すためにしようとはならないと言います。限界はかなり厳しいようです。

あなたのオプション:いずれかの簡単で

  • ストアのデータは、一時ファイルを読み込み、周りにそのファイルへのファイルポインタを渡します。
  • あなたのアプリのApplicationインスタンスにデータを格納します。シングルトンではなく、(MyAppInstance) context.getApplicationContext()からアクセス可能なものにします。最後のオプションの

例:

注:データへのアクセスを同期する場合があります。

public class MyAppInstance extends Application { 
    private Object data = null; 

    public void setMyData(Object data){ 
     this.data = data; 
    } 

    public Object getMyData(){ 
     return data; 
    } 

} 

MyAppInstance app = (MyAppInstance) context.getApplicationContext(); 

app.setMyData(whatever); 
whatever = app.getMyData(); 
+1

さて、私はアプリケーションのインスタンスを使用して疲れています(このブログの投稿は、なぜhttp://www.developerphil.com/dont-store-data-in-the-application-object/)の良い説明ですが、おそらくシングルトンを使うよりも安全だと言いました。 –

+0

ブログの記事で説明されている問題は一般的なピットの秋ですが、シングルトンを使用する場合も同じ問題が発生します。つまり、適切に使用されていれば、アプリケーションインスタンスはおそらくあなたの最良のチャンスです。 –

関連する問題