【问题标题】:Destroy Activity when another Activity is Stopped当另一个 Activity 停止时销毁 Activity
【发布时间】:2014-02-23 09:18:50
【问题描述】:

我有一个活动 A(一个列表视图),它调用活动 B(一个从数据库中检索图像分配的适配器)。当用户点击 Activity A 的返回按钮时,应用返回主菜单。

问题是我仍然可以看到 Activity B 正在运行,并从数据库中获取所有数据,耗尽了宝贵的内存。

有没有办法在按下 Activity A 后退按钮时可以销毁 Activity B?

谢谢 夏兰

Activity A 是一个列表活动,它打开 DB,获取光标对象,发送到 Itemadpter 类以填充列表视图:

// get the cursor from database 

                        ViewListOfDives.data = new diveDataBase(ViewListOfDives.this);
                        ViewListOfDives.data.open();
                        // get cursor object holding all data, use a asynch inner class to load 
                        cursor = data.getCursorData();
//check if data available
                        if(cursor!=null && cursor.getCount()>0){
                        // get customised array adoater list
                        adapter = new ItemAdapter(ViewListOfDives.this, cursor);
                        }else{

                                //display o dives in data base message and finish this activity
                                displayDialog();

                        }
                        ViewListOfDives.this.setListAdapter(adapter);
                        ViewListOfDives.data.close();

编辑:CursorAdapter 类,这里的图像是从数据库中检索的,调整大小,并设置为列表视图的 ImageView .....即使 ListAcivity 已经用完大量内存,这个过程仍在继续

这一切都是在异步内部类中进行的......

public ItemAdapter(Context context, Cursor c) {
            super(context, c);
            mContext = context;
            mLayoutInflater = LayoutInflater.from(context); 

          // mContext.
           // noOfRows = c.getCount()+1;//use row count to get no of dives
        }//end constructor

//do in background method
//retrival of images from DB and resizing is carried out in a asynch class
String diveImagePath = imagePath[0];

                     File imagePathFile = new File(diveImagePath); 
                     try {
                        final int IMAGE_MAX_SIZE = 3000;
                            FileInputStream streamIn = new FileInputStream(imagePathFile);

                        // Decode image size and setInJBounds = true to avoid auto memory allocation for large image
                            BitmapFactory.Options o = new BitmapFactory.Options();
                            o.inJustDecodeBounds = true;
                           BitmapFactory.decodeStream(streamIn, null, o);
                             streamIn.close();

                            int scale = 1;
                            while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > 
                           IMAGE_MAX_SIZE) {
                               scale++;
                            }

                           //get orginal width of image before loaded into memory 
                           Log.d(TAG, "scale = " + scale + ", orig-width: " + o.outWidth + "  orig-height: " + o.outHeight);


                           Bitmap b = null;
                           streamIn = new FileInputStream(imagePathFile);
                            if (scale > 1) {
                                scale--;
                                // scale to max possible inSampleSize that still yields an image
                                // larger than target, inSampleSize loads the image into memor by a factor of its integer value
                                o = new BitmapFactory.Options();
                                o.inSampleSize = scale;
                            // Decode bitmap with inSampleSize set
                               o.inJustDecodeBounds = false;

                               b = BitmapFactory.decodeStream(streamIn, null, o);
                              resizedImage = reSizeImage(b);
                             streamIn.close();
                             b.recycle();
                             System.gc();

                    } else {
                        bitmap = BitmapFactory.decodeStream(streamIn);
                       resizedImage = reSizeImage(bitmap);
                      streamIn.close();
                       System.gc();
                    }

@Override
                protected void onPostExecute(Bitmap bitmap) {

                    ImageView displayImage = (ImageView) view.findViewById(R.id.iv_list_image);
                    if(bitmap!=null){

                        displayImage.setBackground(null);
                        //resizedImage = reSizeImage(bitmap);

                        displayImage.setImageBitmap(resizedImage);


                    }else{
                        //Toast.makeText(context, "No Image Found!! Usimng default", Toast.LENGTH_LONG).show();
                        displayImage.setBackgroundResource(R.drawable.logdive3);
                    }

编辑:此代码有效: 取消 ListActivity 异步任务(依次调用 CursorAdpter ayscnh 任务以从数据库加载图像),并获取 CursorAdtpter aysnch 任务引用并取消此任务.....

//in the ListActivity class
@Override
    public void onBackPressed() {
        // try to quit cursoradpter from reriving and upload data when user clicks back button
        super.onBackPressed();
        //cancel the background process of asycn task
        getCursorAysnch.cancel(true);

        //now cancel backgound process of Itemadatpetr class to free memory and stop loading images from DB
        adapter.getImageAsynch.cancel(true);
        Log.d("Vuiew List Dives:", "Back button pressed");

【问题讨论】:

  • B 是一个活动还是一个适配器类??
  • B 是一个 cursoradapter 类......
  • 为什么不通过适配器的上下文完成活动..
  • 在onBackPressed方法中,调用super.onBackPressed和finish(),如果是适配器类,可以做((ActivityB)context).finish();
  • 所以看到这个停止 AsyncTask 线程:stackoverflow.com/questions/7821284/…

标签: android android-activity lifecycle


【解决方案1】:

好的。您正在通过适配器类在活动 B 中做所有事情。因此,如果您想在后退键中停止 B,那么只需在您的 onBackKeyPressed 方法中完成它。为此,您可以尝试一些建议(因为我不知道您当前的流程)。

1:调用finish() 覆盖onBackKeyPressed()

2:在完成所有加载内容后,在您的适配器类中,您还可以通过当前上下文调用完成。但是在这里你必须通过强制转换为活动来完成所有事情,因为适配器不是活动,我们知道只有活动可以完成。

是的,演员应该像 Rat-a-tat-a-tat Ratatouille 所说的那样,但是在你完成从数据库中获取所有东西之后再做,否则它会停止你从活动 B 中运行的所有东西。

【讨论】:

  • 好的,第 1 点没问题,适配器类仍在后台运行。不明白第 2 点,如何退出 Adpter 类在后台检索数据...上面的代码错误
  • 你能在这里展示你的适配器类吗?你怎么知道它还在运行?
  • 是的,我会发布日志猫,它从数据库中检索图像并在 ListActivity 完成后不断调整它们的大小。
  • 我认为问题出在你的 close 方法中。你必须在 adapter = new ItemAdapter(ViewListOfDives.this, cursor); 之后关闭它if 子句中的行..尝试完美关闭数据库。
  • hmmm 在 ListAdpter 设置为自定义适配器之后,我在 onPostExecute 中的 LstActivity 中关闭数据库,并且在 onBackPressed() 方法中也关闭了数据库......它在 do-in-backgound 方法中打开适配器类被实例化
【解决方案2】:

取消 ListActivity 异步任务的代码(它依次调用 CursorAdpter ayscnh 任务以从数据库加载图像),并获取 CursorAdtpter aysnch 任务参考并取消此任务.....请参阅问题的编辑代码,谢谢大家

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 1970-01-01
    • 2011-02-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多