Android:我的应用程序内存超过 300MB 的 ram 只是闲置

Android: my app memory over 300MB of ram just on idle

我注意到我的应用程序使用了大量内存,所以我使用了探查器,发现一旦应用程序启动并出现启动画面,即使在启动主程序或任何其他应用程序之前启动时,应用程序也会超过 150 + MB activity.

更新:我解决了所有的内存泄漏问题,但我的应用程序仍然在使用 recycleview 浏览 MainActivity 时在我的真实 phone 上使用近 300+ MB 的内存。

LeakCanary 和我一直给我错误,这是内存泄漏的原因所以任何人都请告诉我如何解决它 >

如果您点击了任何 recyclerview 项目:

[]

Activity代码:

public class WorkDetailsActivity extends AppCompatActivity {

    ArrayList<String> imagesFromURL = new ArrayList<String>();
    ActivityWorkDetailsBinding binding;
    DatabaseReference databaseReference;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityWorkDetailsBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        String workUid_details = getIntent().getExtras().getString("UID_Details");
        String title = getIntent().getExtras().getString("name");
        String description = getIntent().getExtras().getString("description");
        String location = getIntent().getExtras().getString("location");
        String path = getIntent().getExtras().getString("path");


        databaseReference = FirebaseDatabase.getInstance().getReference().child("Work").child(path);
        databaseReference.child(workUid_details).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                binding.workDetailsTitle.setText(title);
                binding.workDetailsDescription.setText(description);
                binding.workDetailsLocation.setText(location);
                binding.getUIDDetails.setText(workUid_details);

                for (DataSnapshot dataSnapshot : snapshot.child("images").getChildren()) {
                    String value = String.valueOf(dataSnapshot.child("image").getValue());
                    imagesFromURL.add(value);
                    //Log.i("Value", String.valueOf(imagesFromURL));
                }
                initRecyclerView();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
    }

    private void initRecyclerView(){
        binding.workDetailsImage.setNestedScrollingEnabled(false);
        binding.workDetailsImage.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        binding.workDetailsImage.setHasFixedSize(true);
        PrivateRecyclerAdapter adapter = new PrivateRecyclerAdapter(this, imagesFromURL);
        binding.workDetailsImage.setAdapter(adapter);
        binding.progressBar.setVisibility(View.VISIBLE);

       /* //Add Divider between recyclerView items
        DividerItemDecoration itemDecorator = new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL);
        binding.workDetailsImage.addItemDecoration(itemDecorator);

        final int radius = getResources().getDimensionPixelSize(R.dimen.radius);
        final int dotsHeight = getResources().getDimensionPixelSize(R.dimen.dots_height);
        final int color = ContextCompat.getColor(this, R.color.green);
        binding.workDetailsImage.addItemDecoration(new DotsIndicatorDecoration(radius, radius * 2, dotsHeight, color, color));
        binding.workDetailsImage.setOnFlingListener(null);
        new PagerSnapHelper().attachToRecyclerView(binding.workDetailsImage);*/
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        imagesFromURL = null;
        binding.workDetailsImage.setAdapter(null);
        binding.workDetailsTitle.setText(null);
        binding.workDetailsLocation.setText(null);
        binding.workDetailsDescription.setText(null);
        binding.getUIDDetails.setText(null);
        binding.workDetailsImage.setAdapter(null);
    }

上述代码的问题在于您将值事件侦听器注册为匿名实现。它将保存 activity 的引用。根据 LeakCanary 堆栈跟踪,您的 activity 处于销毁状态,但由于侦听器,activity 实例无法被垃圾收集,因此它被泄漏了。您需要做的是添加和删除侦听器,如下所示。

  1. 创建 ValueEventListener 实例并将其存储在变量中

    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            binding.workDetailsTitle.setText(title);
            binding.workDetailsDescription.setText(description);
            binding.workDetailsLocation.setText(location);
            binding.getUIDDetails.setText(workUid_details);
    
            for (DataSnapshot dataSnapshot : snapshot.child("images").getChildren()) {
                String value = String.valueOf(dataSnapshot.child("image").getValue());
                imagesFromURL.add(value);
                //Log.i("Value", String.valueOf(imagesFromURL));
            }
            initRecyclerView();
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        }
    });
    
  2. 使用

    在activity生命周期的onStart方法中注册它
    @Override
    protected void onStart() {
    databaseReference.child(workUid_details).addValueEventListener(valueEventListener);
    }
    
  3. 使用

    删除 activity 生命周期的 onStop 方法中的侦听器
    @Override
    protected void onStop() {
    databaseReference.child(workUid_details).removeEventListener(valueEventListener);
    }