我正在开发一个android应用程序。在我的活动中,我有一个RecyclerView,recyclerview有数百个项目,其中大部分是图像和视频(但我只显示视频缩略图而不加载视频)。
在recyclerview适配器中,我重写了onViewRecycled方法,并使用glide clear方法和其他本机方法清除了所有图像:
Glide.with(holder.itemView.getContext()).clear(holder.postimage);
holder.postimage.setImageDrawable(null);
holder.postimage.setImageBitmap(null);
但是,当ı加载数百个项目时,内存增加并且应用程序第一次出现问题(系统显示“应用程序未响应”消息),然后抛出OutOfMemory错误。
我想知道“这是由于recyclerview引起的吗”,然后我决定打开相同的活动以查看内存是否可以自我清理。
这是我的代码:
startActivity(new Intent(MainActivity.this,MainActivity.class));
finish();
Runtime.getRuntime().gc();
即使我杀死了我以前的活动并在Android Profiler上调用垃圾收集器的内存使用也没有拖延并且应用程序引发oom错误。 我还清除了所有列表,将ondestroy方法上的所有引用都设置为null并将所有侦听器都设置为null,但是垃圾收集器不执行任何操作?
我该如何解决?
编辑这是我的主页
我所有的变量都是全局变量:
Spinner spinner;
List<BasePost> list;
DatabaseReference reference;
FloatingActionButton fab;
SwipeRefreshLayout swipeRefreshLayout;
RecyclerView recyclerView;
private int yüklenen;
private boolean postson=false;
private LinearLayoutManager linearLayoutManager;
NRAdapter adapter;
private boolean loading=true;
这基本上就是我设置主页的方式(我并没有添加所有代码,而只是基本结构)
loading=true;
spinner.setEnabled(false);
swipeRefreshLayout.setRefreshing(true);
yüklenen=0;
postson=false;
linearLayoutManager=null;
adapter=null;
list=null;
reference=FirebaseDatabase.getInstance().getReference().child("posts").child(FirebaseAuth.getInstance().getUid());
linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
list=new ArrayList<>();
adapter = new NRAdapter();
adapter.setHasStableIds(true);
recyclerView.setAdapter(adapter);
reference.limitToFirst(1).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
List<String> lo = new ArrayList<>();
for(DataSnapshot ds:dataSnapshot.getChildren()){
lo.add(ds.getKey());
}
if(lo.size()==0){
adapter.setContext(getContext(),list,"",reference);
list.add(new BasePost(null,null,"boş"));
adapter.notifyDataSetChanged();
postson=true;
swipeRefreshLayout.setRefreshing(false);
spinner.setEnabled(true);
}
else{
FirebaseDatabase.getInstance().getReference().child("admobadunitid").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String admobadunitid=dataSnapshot.getValue().toString();
adapter.setContext(getContext(),list,admobadunitid,reference);
loaddata();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
这就是我加载数据的方式。我从Internet下载数据,然后将firease用作数据库。据我所知,firebase数据检索过程是asynctask
yüklenen=0;
int eski= list.size();
List<String> gecicilist=new ArrayList<>();
List<BasePost> gecicilistbase=new ArrayList<>();
reference.limitToLast(20).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds:dataSnapshot.getChildren()){
gecicilist.add(ds.getKey());
}
Collections.reverse(gecicilist);
for(int i=gecicilist.size();i>0;i--){
if(içerikkontrol(list,gecicilist.get(i-1))){
gecicilist.remove(i-1);
}
}
if(gecicilist.size()>0){
for(int i=0;i<gecicilist.size();i++){
int finalI = i;
FirebaseDatabase.getInstance().getReference().child("postall").child(gecicilist.get(i)).child("info").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
BasePost basePost = new BasePost();
basePost.setPost(dataSnapshot.getValue(Post.class));
FirebaseDatabase.getInstance().getReference().child("users").child(basePost.getPost().getUid()).child("about").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
basePost.setUser(dataSnapshot.getValue(User.class));
basePost.setKey(gecicilist.get(finalI));
yüklenen++;
gecicilistbase.add(basePost);
if(yüklenen==gecicilist.size()){
yüklenen=0;
for(int i=0;i<gecicilist.size();i++){
if(list.size()!=0&&list.size()%6==0){
i--;
list.add(new BasePost(null,null,"reklam"));
}
else{
for(int m=0;m<gecicilistbase.size();m++){
if(gecicilistbase.get(m).getKey().equals(gecicilist.get(i))){
list.add(gecicilistbase.get(m));
}
}
}
}
gecicilist.clear();
if(gecicilistbase.size()==0){
postson=true;
}
gecicilistbase.clear();
if(list.size()==0){
list.add(new BasePost(null,null,"boş"));
postson=true;
}
swipeRefreshLayout.setRefreshing(false);
adapter.notifyDataSetChanged();
spinner.setEnabled(true);
loading=false;
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
else{
reference.child(gecicilist.get(finalI)).removeValue();
yüklenen++;
if(yüklenen==gecicilist.size()){
yüklenen=0;
for(int i=0;i<gecicilist.size();i++){
if(list.size()!=0&&list.size()%6==0){
i--;
list.add(new BasePost(null,null,"reklam"));
}
else{
for(int m=0;m<gecicilistbase.size();m++){
if(gecicilistbase.get(m).getKey().equals(gecicilist.get(i))){
list.add(gecicilistbase.get(m));
}
}
}
}
gecicilist.clear();
if(gecicilistbase.size()==0){
postson=true;
}
gecicilistbase.clear();
if(list.size()==0){
list.add(new BasePost(null,null,"boş"));
postson=true;
}
swipeRefreshLayout.setRefreshing(false);
adapter.notifyDataSetChanged();
spinner.setEnabled(true);
loading=false;
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
答案 0 :(得分:0)
正如我们在Glide documentation page上看到的那样,负载会自动清除:
尽管清除不需要的货物是一种很好的做法,但您不必这样做。实际上,当您传递给Glide.with()的Activity或Fragment被销毁时,Glide会自动清除负载并回收该负载使用的所有资源。
这使我相信其他地方出了问题。 很难确定到底发生了什么,因为几乎没有提供源代码。 也许您可以为我们提供更多相关的源代码。