我有下一个问题,我正在创建一个自定义适配器的列表视图,我正在使用异步任务从JSON url(文本和图像URL)下载适配器的数据,然后我设置了适配器在列表中,我使用毕加索库下载图像,现在我的应用程序工作正常,它不会崩溃但是当我开始另一个活动时,我得到了这个:
E / JavaBinder:!!!失败的粘合剂交易!!!即使新活动为空,我也会收到错误,我正在使用moto G.我已经使用DDMS和Eclipse MAT分析了堆,我还没有发现我的代码是否导致内存泄漏。多次从一个活动变为另一个活动我在logcat中得到了这个:
09-04 10:37:54.827 30603-30603/mx.f403.whimlike E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
09-04 10:38:01.793 30603-30603/mx.f403.whimlike D/dalvikvm﹕ GC_FOR_ALLOC freed 1178K, 24% free 13642K/17876K, paused 21ms, total 21ms
09-04 10:38:02.939 30603-30603/mx.f403.whimlike E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
09-04 10:38:07.235 30603-30603/mx.f403.whimlike D/dalvikvm﹕ GC_FOR_ALLOC freed 1008K, 24% free 13657K/17876K, paused 20ms, total 20ms
09-04 10:38:14.484 30603-30603/mx.f403.whimlike E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
09-04 10:38:15.497 30603-30603/mx.f403.whimlike D/dalvikvm﹕ GC_FOR_ALLOC freed 1065K, 24% free 13656K/17876K, paused 18ms, total 18ms
09-04 10:38:16.371 30603-30603/mx.f403.whimlike E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
09-04 10:38:16.688 30603-30603/mx.f403.whimlike D/dalvikvm﹕ GC_FOR_ALLOC freed 1007K, 24% free 13628K/17876K, paused 19ms, total 19ms
09-04 10:38:17.491 30603-30603/mx.f403.whimlike E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
09-04 10:38:17.781 30603-30603/mx.f403.whimlike D/dalvikvm﹕ GC_FOR_ALLOC freed 1020K, 24% free 13653K/17876K, paused 27ms, total 27ms
正如您所看到的,内存堆没有增加,但我以同样的方式得到错误。
我不认为问题在于我为第一个活动下载的位图,因为我评论了涉及位图的所有代码行,我还评论了asynctasks并且问题继续出现,无论如何我要把适配器放在这里:
class ClientListAdapter extends BaseAdapter {
private Context context;
private ClientList clients;
private ClientList arrayList;
public ClientListAdapter(Context context, ClientList clients) {
this.context = context;
this.clients = clients;
this.arrayList = new ClientList();
this.arrayList.addAll(clients);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Client client = clients.get(position);
ClientHolder clientHolder = new ClientHolder();
if(convertView == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
convertView = inflater.inflate(R.layout.client_list_item,parent,false);
clientHolder.clientName = (TextView) convertView.findViewById(R.id.client_name);
clientHolder.clientImage = (ImageView) convertView.findViewById(R.id.client_image);
convertView.setTag(clientHolder);
}
else{
clientHolder = (ClientHolder) convertView.getTag();
}
if (client != null) {
clientHolder.clientImage.setImageResource(R.drawable.ic_launcher);
Picasso.with(context).load(client.getClientImageUrl()).into(clientHolder.clientImage);
clientHolder.clientName.setText(client.getName());
}
return convertView;
}
static class ClientHolder{
TextView clientName;
ImageView clientImage;
}
我下载了Eclipse MAT,它显示了泄漏可能的原因,但我不太清楚这意味着什么,这是Eclipse MAT的结果:
**Problem Suspect 1**
The class "android.content.res.Resources", loaded by "<system class loader>", occupies 2,968,072 (14.65%) bytes. The memory is accumulated in one instance of "android.util.LongSparseArray[]" loaded by "<system class loader>".
Keywords
android.util.LongSparseArray[]
android.content.res.Resources
**Problem Suspect 2**
16 instances of "byte[]", loaded by "<system class loader>" occupy 5,860,824 (28.92%) bytes.
Biggest instances:
•byte[1705600] @ 0x432a2f28 ..........................................y...x...v...v...v...u...t...t...t...t...t...t...t...t...s...s...s...s...r...r...q...q...n...n...n...n...m...m...l...l...l...l...l...l...k...k...j...j...[...[...\...[...\...Y...\...Z...[...Z...\...Z...Z...Y...Z...Z.... - 1,705,616 (8.42%) bytes.
•byte[1536000] @ 0x42715a48 ................................................................................................................................................................................................................................................................... - 1,536,016 (7.58%) bytes.
•byte[1500000] @ 0x43751fd0 ..w...x...{...|...|...{...y...x...t...v...s...t...l...h...`...^...J...H...F...F...H...J...I...H...F...F...E...D...C...A...A...@...E...E...E...E...E...E...E...E...F...F...F...E...E...D...D...D...;...;...;...;...;...;...;...;...;...9..~8...9...;...<...;...9.... - 1,500,016 (7.40%) bytes.
•byte[788544] @ 0x42ab6ab8 ................................................................................................................................................................................................................................................................... - 788,560 (3.89%) bytes.
•byte[293304] @ 0x426c7e78 ....LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL... - 293,320 (1.45%) bytes.
Keywords
byte[]
**Problem Suspect 3**
20 instances of "android.graphics.Bitmap", loaded by "<system class loader>" occupy 3,213,736 (15.86%) bytes.
Biggest instances:
•android.graphics.Bitmap @ 0x4227b8f0 - 1,127,584 (5.56%) bytes.
•android.graphics.Bitmap @ 0x42998158 - 640,064 (3.16%) bytes.
•android.graphics.Bitmap @ 0x42cbf0a8 - 367,296 (1.81%) bytes.
•android.graphics.Bitmap @ 0x42d21008 - 360,064 (1.78%) bytes.
•android.graphics.Bitmap @ 0x428e01f8 - 293,368 (1.45%) bytes.
Keywords
android.graphics.Bitmap
**Problem Suspect 4**
168 instances of "android.graphics.NinePatch", loaded by "<system class loader>" occupy 2,170,152 (10.71%) bytes. These instances are referenced from one instance of "java.lang.Object[]", loaded by "<system class loader>"
Keywords
java.lang.Object[]
android.graphics.NinePatch
**Hint 1**
The problem suspects 1 and 4 may be related, because the reference chains to them have a common beginning.
在某些博客中,我读过您不应该提及活动的参考,也许可能是这样,但我不知道我的代码的哪个部分适用以及如何解决它,在这里是我的主要活动和我认为问题所在的片段:
public class MainActivity extends ActionBarActivity implements LoggedInFragment.SetUserInfoInterface{
// Constant keys for passing data between Activities
public static final String CLIENTLINK = "ClientLink";
public static final String CLIENTID = "ClientId";
public static final String DEBATEFLAG = "DebateFlag";
public static final String USERID = "UserId";
public static final String SHOW_EMAIL_ASSIGN_DIALOG_ADVICE = "Show email assign dialog advice";
// Constant id's for showing logged in and logged out fragments
private static final int LOGGED_OUT = 0;
private static final int LOGGED_IN = 1;
private static final int SETTINGS = 2;
private static final int FRAGMENT_COUNT = SETTINGS + 1;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
// Flag to know if a fragment is resumed
private boolean isResumed = false;
public String userId;
// Creates a UiHelper to get a call when a session changes
private UiLifecycleHelper uiHelper;
// Creates a callback that does shows a fragment depending of the state of the session, this
// callback calls the function onSessionStateChange.
private Session.StatusCallback callback =
new Session.StatusCallback() {
@Override
public void call(Session session,
SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set uiHelper to get the callback created previously
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
fragments[LOGGED_OUT] = fm.findFragmentById(R.id.loggedOutFragment);
fragments[LOGGED_IN] = fm.findFragmentById(R.id.loggedInFragment);
fragments[SETTINGS] = fm.findFragmentById(R.id.customSettingsFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(Fragment fragment : fragments){
transaction.hide(fragment);
}
transaction.commit();
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return (netInfo != null && netInfo.isConnected());
}
private void showFragment(int fragmentIndex, boolean addToBackStack) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
for (int i = 0; i < fragments.length; i++) {
if (i == fragmentIndex) {
transaction.show(fragments[i]);
} else {
transaction.hide(fragments[i]);
}
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
// Only make changes if the activity is visible
if (isResumed) {
FragmentManager manager = getSupportFragmentManager();
// Get the number of entries in the back stack
int backStackSize = manager.getBackStackEntryCount();
// Clear the back stack
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
if (state.isOpened()) {
// If the session state is open:
// Show the authenticated fragment
showFragment(LOGGED_IN, false);
} else if (state.isClosed()) {
// If the session state is closed:
// Show the login fragment
showFragment(LOGGED_OUT, false);
}
}
}
@Override
protected void onResumeFragments() {
super.onResumeFragments();
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// if the session is already open,
// try to show the LoggedInFragment
showFragment(LOGGED_IN, false);
} else {
// otherwise present the LoggedOutFragment
// and ask the person to login.
showFragment(LOGGED_OUT, false);
}
}
public void closeSession(){
Session session = Session.getActiveSession();
session.close();
}
@Override
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
}
@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
isResumed = false;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
public void showPromptNoInternet() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setPositiveButton(R.string.button_accept, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setTitle(getString(R.string.no_internet_dialog_title));
builder.setMessage(getString(R.string.no_internet_dialog_message));
AlertDialog dlg = builder.create();
dlg.show();
}
public void showSortDialog(){
FragmentManager fm = getSupportFragmentManager();
final LoggedInFragment loggedInFragment = (LoggedInFragment)fm.findFragmentById(R.id.loggedInFragment);
ArrayAdapter<String> sorting_forms = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
sorting_forms.add(getString(R.string.sort_ascending_order));
sorting_forms.add(getString(R.string.sort_descending_order));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Ordenar")
.setAdapter(sorting_forms, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which){
case 0:
loggedInFragment.sortClientList("ascend");
break;
case 1:
loggedInFragment.sortClientList("descend");
break;
}
}
});
AlertDialog dlg = builder.create();
dlg.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.settings, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
switch(item.getItemId()) {
case R.id.settings:
transaction.show(fragments[SETTINGS]);
transaction.hide(fragments[LOGGED_IN]);
transaction.addToBackStack(null);
transaction.commit();
return true;
case R.id.action_my_coupons:
Intent i = new Intent(this, CouponListActivity.class);
i.putExtra(USERID, userId);
startActivity(i);
return true;
case R.id.view_recent_promotions:
Intent recentPromoListActivityIntent = new Intent(this, RecentPromotionListActivity.class);
recentPromoListActivityIntent.putExtra(USERID, userId);
recentPromoListActivityIntent.putExtra(MainActivity.DEBATEFLAG,false);
startActivity(recentPromoListActivityIntent);
return true;
case R.id.action_sort:
showSortDialog();
return true;
default:
super.onOptionsItemSelected(item);
}
return false;
}
@Override
public void setUserId(String userId) {
this.userId = userId;
}
}
片段:
public class LoggedInFragment extends Fragment implements LoadClientsAsyncTask.ClientAsyncResponse, View.OnClickListener{
public String userId;
private ClientList clients;
private ClientListAdapter adapter;
private ListView clientList;
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
public SetUserInfoInterface mCallback = null;
public interface SetUserInfoInterface {
public void setUserId(String userId);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (SetUserInfoInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(),callback);
uiHelper.onCreate(savedInstanceState);
Session session = Session.getActiveSession();
if(session != null){
makeMeRequest(session);
}
Log.d("panda", "Logged in Creado");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = (inflater.inflate(R.layout.logged_in, container, false));
LinearLayout debateLayout = (LinearLayout) view.findViewById(R.id.debate_layout);
debateLayout.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
Intent debatePromoListActivityIntent = new Intent(getActivity(), RecentPromotionListActivity.class);
debatePromoListActivityIntent.putExtra(MainActivity.USERID, userId);
debatePromoListActivityIntent.putExtra(MainActivity.DEBATEFLAG,true);
startActivity(debatePromoListActivityIntent);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception){
// If the session is opened and is not null
if (session != null && session.isOpened() && ((MainActivity)getActivity()).isOnline()) {
// Get the user's data
makeMeRequest(session);
}
}
private void makeMeRequest(final Session session){
final Request request = Request.newMeRequest(session, new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser user, Response response) {
if (session == Session.getActiveSession()) {
if (user != null) {
userId = user.getId();
String userName = user.getName();
String userEmail = user.getProperty("email").toString();
mCallback.setUserId(userId);
postData(userId, userName, userEmail);
}
}
}
});
request.executeAsync();
}
private void setListListener(ClientList clients) {
if (ApplicationCheckActivityVisibility.isActivityVisible()) {
adapter = new ClientListAdapter(getActivity(),R.layout.client_list_item,clients);
View view = getView();
clientList = (ListView) view.findViewById(R.id.clients_list);
clientList.setAdapter(adapter);
clientList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
Client chosenClient = (Client) clientList.getItemAtPosition(position);
String clientLink = chosenClient.getLink();
String clientId = chosenClient.getId();
Intent i = new Intent(getActivity(), PromoListActivity.class);
i.putExtra(MainActivity.CLIENTLINK, clientLink);
i.putExtra(MainActivity.CLIENTID, clientId);
i.putExtra(MainActivity.USERID, userId);
startActivity(i);
}
});
}
}
public void sortClientList(String form){
if(form.matches("ascend")){
Collections.sort(clients, ClientAscComparator);
}
else if(form.matches("descend")){
Collections.sort(clients, ClientDescComparator);
}
adapter.notifyDataSetChanged();
}
public Comparator<Client> ClientAscComparator = new Comparator<Client>() {
public int compare(Client client1, Client client2) {
String clientName1 = client1.getName();
String clientName2 = client2.getName();
return clientName1.compareTo(clientName2);
}
};
public Comparator<Client> ClientDescComparator = new Comparator<Client>() {
public int compare(Client client1, Client client2) {
String clientName1 = client1.getName();
String clientName2 = client2.getName();
return clientName2.compareTo(clientName1);
}
};
@Override
public void processFinish(ClientList clients) {
View view = getView();
if(view != null) {
RelativeLayout loadingPanel = (RelativeLayout) view.findViewById(R.id.loading_panel);
loadingPanel.setVisibility(View.GONE);
}
if(clients != null){
this.clients = clients;
setListListener(clients);
}
else{
Toast.makeText(getActivity(), R.string.no_restaurants_right_now, Toast.LENGTH_SHORT).show();
}
}
public void postData(String userId,String userName,String userEmail){
if(((MainActivity)getActivity()).isOnline()) {
HttpPostAsyncTask httpPostAsyncTask = new HttpPostAsyncTask(userId, userName, userEmail, getFragmentManager());
httpPostAsyncTask.execute();
}
else
{
((MainActivity)getActivity()).showPromptNoInternet();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onResume() {
super.onResume();
ApplicationCheckActivityVisibility.activityResumed();
if(((MainActivity)getActivity()).isOnline()) {
LoadClientsAsyncTask asyncTask = new LoadClientsAsyncTask();
asyncTask.delegate = this;
asyncTask.execute();
}
else
{
((MainActivity)getActivity()).showPromptNoInternet();
}
uiHelper.onResume();
}
@Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
uiHelper.onSaveInstanceState(bundle);
}
@Override
public void onPause() {
super.onPause();
ApplicationCheckActivityVisibility.activityPaused();
uiHelper.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
}
当应用程序调用intent并进入其他活动时会出现错误,所以我认为我没有正确地清理第一个活动的内存并且堆积在其中两个导致错误。但正如您在logcat中看到的那样,当我从一个活动更改为另一个活动时,内存堆是稳定的并且不会增加。有时我也会得到这个:
I/dalvikvm﹕ threadid=3: reacting to signal 3
更新: 我观察到的另一件事是我在三星ACE,Moto Razr Z3和Galaxy Tab 2中运行代码,即使这些设备的内存比Moto g少,也不会出现错误,这可能是错误或摩托车上的错误?
答案 0 :(得分:6)
捆绑包可以包含多少数据存在一些限制。如果您的捆绑或意图附加功能太大,您可能会收到此错误。您是否将数据传递到捆绑包中?