2

異常TransactionTooLargeException在牛軋糖

05-12 15:42:45.791 11043-11043/ E/UncaughtException: java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 631792 bytes 
                     at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3776) 
                     at android.os.Handler.handleCallback(Handler.java:751) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:154) 
                     at android.app.ActivityThread.main(ActivityThread.java:6123) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
                    Caused by: android.os.TransactionTooLargeException: data parcel size 631792 bytes 
                     at android.os.BinderProxy.transactNative(Native Method) 
                     at android.os.BinderProxy.transact(Binder.java:615) 
                     at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3700) 
                     at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3768) 
                     at android.os.Handler.handleCallback(Handler.java:751)  
                     at android.os.Handler.dispatchMessage(Handler.java:95)  
                     at android.os.Looper.loop(Looper.java:154)  
                     at android.app.ActivityThread.main(ActivityThread.java:6123)  
                     at java.lang.reflect.Method.invoke(Native Method)  
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)  
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)  
05-12 15:42:47.247 11043-11043/ E/AndroidRuntime: FATAL EXCEPTION: main 
                   Process: , PID: 11043 
                   java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 631792 bytes 
                    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3776) 
                    at android.os.Handler.handleCallback(Handler.java:751) 
                    at android.os.Handler.dispatchMessage(Handler.java:95) 
                    at android.os.Looper.loop(Looper.java:154) 
                    at android.app.ActivityThread.main(ActivityThread.java:6123) 
                    at java.lang.reflect.Method.invoke(Native Method) 
                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
                   Caused by: android.os.TransactionTooLargeException: data parcel size 631792 bytes 
                    at android.os.BinderProxy.transactNative(Native Method) 
                    at android.os.BinderProxy.transact(Binder.java:615) 
                    at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3700) 
                    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3768) 
                    at android.os.Handler.handleCallback(Handler.java:751)  
                    at android.os.Handler.dispatchMessage(Handler.java:95)  
                    at android.os.Looper.loop(Looper.java:154)  
                    at android.app.ActivityThread.main(ActivityThread.java:6123)  
                    at java.lang.reflect.Method.invoke(Native Method)  
                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)  
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)  

片段OnItemClick: -

listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, 
           long id) { 

      Bundle bundle = new Bundle(); 
      ProdModel mProdModel = prodList.get(position); 
      bundle.putSerializable("object", mProdModel); 
      Intent intent = new Intent(getActivity(), DetailActivity.class); 
      intent.putExtra("bundle", bundle); 
      startActivityForResult(intent, 1); 

     } 

    }); 

在DetailActivity,

Bundle bundle = getIntent().getBundleExtra("bundle"); 
    if (bundle != null) { 
     ProdModel model = (ProdModel) bundle.getSerializable("object"); 
    } 

DetailActivity艙單,

<activity 
     android:name="com.mass.mysample.DetailActivity" 
     android:screenOrientation="portrait" /> 

圖像加載使用畢加索,

Picasso.with(this).load(model.getImage()) 
      .placeholder(R.drawable.logo_without) 
      .fit().into(productimage); 

模型類從TabActivity

public class ProdModel implements Serializable { 
private String seller_id; 
String name; 
private String image; 
private float price; 
private float specialprice; 
private String entity_id; 
private String productNumQuantity; 
private String storetitle; 
private String description; 
private String discount; 
private String max_price; 
private String store_name; 
private String StoreUrl; 

public String getProductNumQuantity() { 
    return productNumQuantity; 
} 

public void setProductNumQuantity(String productNumQuantity) { 
    this.productNumQuantity = productNumQuantity; 
} 

public String getDiscount() { 
    return discount; 
} 

public void setDiscount(String discount) { 
    this.discount = discount; 
} 

public String getMax_price() { 
    return max_price; 
} 

public void setMax_price(String max_price) { 
    this.max_price = max_price; 
} 

public String getStore_name() { 
    return store_name; 
} 

public void setStore_name(String store_name) { 
    this.store_name = store_name; 
} 

public String getStoreUrl() { 
    return StoreUrl; 
} 

public void setStoreUrl(String storeUrl) { 
    StoreUrl = storeUrl; 
} 

public String getStoretitle() { 
    return storetitle; 
} 

public void setStoretitle(String storetitle) { 
    this.storetitle = storetitle; 
} 

public String getSeller_id() { 
    return seller_id; 
} 

public void setSeller_id(String seller_id) { 
    this.seller_id = seller_id; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getImage() { 
    return image; 
} 

public void setImage(String image) { 
    this.image = image; 
} 

public String getEntity_id() { 
    return entity_id; 
} 

public void setEntity_id(String entity_id) { 
    this.entity_id = entity_id; 
} 

public String getDescription() { 
    return description; 
} 

public void setDescription(String description) { 
    this.description = description; 
} 

public float getPrice() { 
    return price; 
} 

public void setPrice(float price) { 
    this.price = price; 
} 

public float getSpecialPrice() { 
    return specialprice; 
} 

public void setSpecialPrice(float specialprice) { 
    this.specialprice = specialprice; 
} 

} 

數據流片段,

1.I have a TabActivity with ViewPager and Fragment. 
2.In Fragment, I have a ListView. 
3.The Data to fragment is passed from view pager adapter by set arguments. 

解我試圖

1.A POJO class that implements Serialization. 
2.I use Picasso to load the image from image URL. 
3.This exception is thrown when OnItemClick on ListView in fragment passes data to DetailActivity to show all passed data. 
4.I get this exception after the DetailActivity load's image and other data then app suddenly crashes. 
5.I pass data in Intent was all POJO Object with Id, Name, Image URL, Price etc., 

注: - 應用程序崩潰只在NOUGAT

最後,修復我實現

改變後改變targetSdkVersion至23日,我的應用程序中的牛軋糖不崩潰太。

所有我必須知道的是這個正確的解決方案或有任何解決方法。

請指導正確的方法。

在此先感謝。

片段

public class ProdFragment extends Fragment { 
ListView listview; 
SharedPreferences spref; 
Boolean isInternetPresent = false; 
ConnectionDetector cd; 

private String toBeDisplayed,CatID; 
private static final String TAG = ProdFragment.class.getSimpleName(); 
String totalProductCart; 
private ArrayList<Root_SubCatModel> subCatList; 
private ArrayList<ProdModel> prodList; 
ProdAdapter adapter; 

public ProdFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    spref = getActivity().getSharedPreferences(getResources().getString(R.string.myPref), 
      Context.MODE_PRIVATE); 
    Bundle bundle = getArguments(); 
    if (bundle != null) { 
     int tabPosition = bundle.getInt("Tab_Position"); 
     toBeDisplayed = bundle.getString("Tab_ToBeDisplayed"); 
     CatID = bundle.getString("CategoryId"); 
     subCatList = (ArrayList<Root_SubCatModel>) bundle.getSerializable("Tab_Data"); 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    final View rootView = inflater.inflate(R.layout.prod_listview, container, false); 

    cd = new ConnectionDetector(getActivity()); 
    listview = (ListView) rootView.findViewById(R.id.prodlist); 
    if (subCatList != null) { 
     adapter = new ProdAdapter(getActivity(), 
       CatID, 
       toBeDisplayed, 
       R.layout.list_product, 
       subCatList, 
       (ProductCartCountListener)getActivity()); 
     listview.setAdapter(adapter); 
     adapter.notifyDataSetChanged(); 

     prodList = new ArrayList<>(); 
     for(int i = 0; i<subCatList.size();i++){ 
      if (subCatList.get(i).getProd() != null) { 
       if(toBeDisplayed.equals("SubCategory")){ 
        if (CatID.equals(subCatList.get(i).getCategory_id())) { 
         this.prodList = subCatList.get(i).getProd(); 
        } 
       }else if(toBeDisplayed.equals("Products")) { 
        this.prodList = subCatList.get(i).getProd(); 
       } 
      } 
     } 

    } 

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, 
           long id) { 

      Bundle bundle = new Bundle(); 
      bundle.putSerializable("object", prodList.get(position)); 
      Intent intent = new Intent(getActivity(), DetailActivity.class); 
      intent.putExtra("bundle", bundle); 
      startActivityForResult(intent,1); 
     } 

    }); 

    return rootView; 
} 

public void showAlertDialog(Context context, String title, String message, Boolean status) { 
    AlertDialog alertDialog = new AlertDialog.Builder(context).create(); 

    // Setting Dialog Title 
    alertDialog.setTitle(title); 

    // Setting Dialog Message 
    alertDialog.setMessage(message); 

    // Setting alert dialog icon 
    //alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail); 

    // Setting OK Button 
    alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int which) { 
     } 
    }); 

    // Showing Alert Message 
    alertDialog.show(); 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == 1) { 
     if (resultCode == Activity.RESULT_OK) { 
      Bundle b = data.getExtras(); 
      if (b != null) { 
       ProdModel myobj = (ProdModel) b.getSerializable("Cart_Quantity"); 
       if (myobj != null) { 
        if (prodList != null) { 
         for (ProdModel P : prodList) { 
          if (P.getEntity_id().equals(myobj.getEntity_id())) { 
           P.setProductNumQuantity(myobj.getProductNumQuantity()); 
          } 
         } 
        } 
        Log.d(TAG,"Product_Id : " + myobj.getEntity_id() 
          + ", Product_Cart_Count : " + myobj.getProductNumQuantity()); 
       } 
      } 
     } else if (resultCode == 0) { 
      Log.d(TAG,"RESULT CANCELLED"); 
     } 
    } 
    adapter.notifyDataSetChanged(); 
    String totalProductCart = spref.getString("Cart_Count_Tool", "0"); 
    Activity activity = getActivity(); 
    if(activity instanceof TabActivity){ 
     TabActivity myActivity = (TabActivity) activity; 
     Toolbar toolbar = (Toolbar) myActivity.findViewById(R.id.back_toolbar); 
     ImageView cart_imageview = (ImageView) toolbar.findViewById(R.id.cart_imageview); 
     cart_imageview.setImageDrawable(myActivity.buildCounterDrawable(
       Integer.parseInt(totalProductCart))); 
    } 
    Log.d(TAG,"RESULT NOTIFIED"); 
} 

public void refreshData(String productId, boolean isAddAsyncTaskComplete, 
         boolean isAddAsyncTaskLimitReached, boolean isDeleteAsyncTaskComplete){ 
    adapter.setQuantityCount(prodList, productId, isAddAsyncTaskComplete, 
      isAddAsyncTaskLimitReached, isDeleteAsyncTaskComplete); 

} 

TabActivity佈局

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

<android.support.design.widget.AppBarLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <android.support.design.widget.TabLayout 
     android:id="@+id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/storeimage" 
     android:textAlignment="center" 
     android:elevation="2dp" 
     android:minHeight="?attr/actionBarSize" 
     app:tabMode="scrollable" 
     app:tabTextColor="@color/color_dark_blue" 
     app:tabSelectedTextColor="@color/color_orange"/> 
</android.support.design.widget.AppBarLayout> 

<android.support.v4.view.ViewPager 
    android:id="@+id/viewpager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 
</android.support.design.widget.CoordinatorLayout> 

的ListView

<FrameLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<ListView 
    android:id="@+id/prodlist" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" /> 

</FrameLayout> 
+0

它是完整的堆棧跟蹤?我記得在一個項目中出現了這個異常,並且頂部堆棧跟蹤表示「過大的事務」,但是當向下滾動時,實際上是由stackOverflowException導致的,因爲我偶然發出了遞歸調用 –

+0

是的,這是我的完整堆棧跟蹤 –

+1

Can你發佈了'onSaveInstanceState()'實現? – azizbekian

回答

6

您正在向setArguments()Fragment傳遞太多數據。您的Fragment將工作,但當它試圖保存其實例狀態時,它會溢出事務緩衝區。如果您的目標是Android 7.0(API 24或更高版本),則會引發RuntimeException。爲了保持向後兼容性並且不破壞現有的應用程序,只有在您定位API 24或更高版本時纔會使用新行爲。如果您的目標是API < 24,則會捕獲事務緩衝區溢出異常並以無提示方式忽略。這意味着您的數據不會被永久保存,您可能(或可能不會)注意到。

您的代碼已損壞。您不應將大量數據傳遞到setArguments()中的Fragment。你可以保存你的數據在你的Activity。當Fragment要訪問數據,它可以總是那麼這樣的事情:

// Get the owning Activity 
MyActivity activity = (MyActivity)getActivity(); 
// Get the data from the Activity 
List<Data> data = activity.getData(); 

在你Activity,寫一個getData()方法,它返回到Fragment需要的任何數據的參考。

通過這種方式,數據保存在Activity中,並且Fragment可以在需要時訪問它。

2

對於當值過大,以適應在交易緩衝區中的文件This Exception拋出。對於一個大項目來說,這可能是一個複雜的問題,您可以在不同的地方通過Intent調用多個操作。

你的例子證明了這個問題,即使是單個對象。你應該改變你的轉移行爲。例如。通過修剪對象,只包含重要的信息。 意圖附加數據應該只有輕量級的信息!


在你比如說你有場,這可能會產生這種問題。可能您正在使用Base64編碼圖像。消息文本的例外情況,僅適用於Android 23.檢查文檔。

public String getImage() { 
    return image; 
} 

public void setImage(String image) { 
    this.image = image; 
} 
5

Android 7.0(Nogat)包含各種系統和API行爲更改。 關於TransactionTooLarge例外:

在安卓7.0,多平臺的API現在已經開始檢查大 有效載荷跨越粘結劑交易被髮送,而現在的系統 重新拋出TransactionTooLargeExceptions爲RuntimeExceptions,默默記錄或抑制他們,而不是 。一個常見的例子是在Activity.onSaveInstanceState()中存儲太多數據,導致 ActivityThread.StopInfo在您的應用 定位到Android 7.0時拋出RuntimeException。

可能的解決方案: 1.將所需對象保存在全局緩存中,並僅將密鑰傳遞給DetailsActivity以檢索該對象。

+0

我覺得你的解決方案並不是最佳實踐。我們應該將對象保存在某個數據庫/文件中,並將密鑰傳遞給新的活動以稍後檢索它。 –

+0

只有在應用程序啓動或應用程序死亡後再次需要時纔將其保存在數據庫/文件中。 如果只需要點擊某個按鈕來顯示詳細信息,請將其保存在內存中,並在應用程序轉到後臺時將其清除。 – abhishesh

相關問題