将片段发送到其他类后,为什么fragment.getActivity()为null?

时间:2015-07-21 07:01:37

标签: android android-fragments android-asynctask

我在Android中实施了GridView

第一个片段使用AsyncTask加载文件并显示在GridView上。当getView被呼叫时。它会调用ExtractThumbnail来阅读缩略图。它工作正常。

它可以通过按钮转向第二个片段。

ExtractThumbnail正在阅读视频和照片的缩略图时,我点击按钮并转到第二个片段。 它由于 java.lang.NullPointerException 而崩溃。

第一个片段的代码如下所示:(我省略了一些不重要的代码)

    public class LocalFileBrowserFragment extends Fragment implements MultiChoiceModeListener{

    public static Executor threadpoolexecutor;
    public static Activity activity;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    mFileListAdapter = new LocalFileListAdapter(inflater, mFileList) ;
    mFileListAdapter.GridAdapter(getActivity());
    activity = getActivity();
    loadfilelistTask = new LoadFileListTask();
    new LoadFileListTask().executeOnExecutor(threadpoolexecutor) ;
    BackButton = (ImageButton) view.findViewById(R.id.BackButton);

    BackButton.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {

                loadfilelistTask.cancel(true);

                Checkurl task = new Checkurl(activity, LocalFileBrowserFragment.this); 
        task.execute();
            }
    });
}


    public class LocalFileListAdapter extends BaseAdapter {

            private LayoutInflater mInflater ;
            private ArrayList<FileNode> mFileList ;
            private static final String TAG = "LocalFileBrowserFragment" ;
            private Context mContext;

            public LocalFileListAdapter(LayoutInflater inflater, ArrayList<FileNode> fileList) {

                mInflater = inflater ;
                mFileList = fileList ;
            }

            public void GridAdapter(Context ctx) {
                // TODO Auto-generated method stub
                mContext = ctx;

            }


            private List<ExtractThumbnail> thumbnailTaskList = new LinkedList<ExtractThumbnail>();

            private class ExtractThumbnail extends AsyncTask<ViewTag, Integer, Bitmap> {
                //Read the Thumbnail.
                ViewTag mViewTag;

                @Override
                protected void onPreExecute() {
                    thumbnailTaskList.add(this);
                    super.onPreExecute();
                }

                @Override
                protected Bitmap doInBackground(ViewTag... params) {

                    mViewTag = params[0];

                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    options.inDither = false;
                    options.inScaled = false;

                    BitmapFactory.decodeFile(mViewTag.mFileNode.mName, options);

                    int imageHeight = options.outHeight;
                    int imageWidth = options.outWidth;
                    int requestedHeight = 64;
                    int requestedWidth = 64;

                    int scaleDownFactor = 0;

                    options.inJustDecodeBounds = false;

                    while (true) {

                        scaleDownFactor++;
                        if (imageHeight / scaleDownFactor <= requestedHeight
                                || imageWidth / scaleDownFactor <= requestedWidth) {

                            scaleDownFactor--;
                            break;
                        }
                    }

                    options.inSampleSize = scaleDownFactor;
                    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                    float scaleFactor = (float) requestedHeight / imageHeight;
                    scaleFactor = Math.max(scaleFactor, (float) requestedWidth
                            / imageWidth);

                    Bitmap originalBitmap = BitmapFactory.decodeFile(
                            mViewTag.mFileNode.mName, options);

                    if (originalBitmap == null) {

                        try {
                            byte[] data = Util.getLibVlcInstance().getThumbnail(
                                    "file://" + mViewTag.mFileNode.mName,
                                    requestedWidth, requestedHeight);
                            if (data != null) {

                                Bitmap thumbnail = Bitmap.createBitmap(requestedWidth,
                                        requestedHeight, Bitmap.Config.ARGB_8888);

                                thumbnail.copyPixelsFromBuffer(ByteBuffer.wrap(data));
                                thumbnail = Util.cropBorders(thumbnail, requestedWidth,
                                        requestedHeight);

                                return thumbnail;
                            }

                        } catch (LibVlcException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        return null;
                    }

                    Bitmap thumbnail = ThumbnailUtils.extractThumbnail(originalBitmap,
                            requestedWidth, requestedHeight);
                    originalBitmap.recycle();

                    return thumbnail;
                }

                @Override
                protected void onPostExecute(Bitmap thumbnail) {

                    Log.i(TAG, "thumbnail = " + thumbnail);
                    if (thumbnail != null) {
                        mViewTag.mThumbnail.setImageBitmap(thumbnail);
                    }
                    thumbnailTaskList.remove(this);
                    mViewTag.mThumbnailTask = null;

                    super.onPostExecute(thumbnail);
                }
            }


            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                ViewTag viewTag ;

                if (convertView == null) {
                    convertView = mInflater.inflate(R.layout.filelist_row, null) ;

                    viewTag = new ViewTag(mContext , (ImageView) convertView.findViewById(R.id.fileListThumbnail);

                    convertView.setTag(viewTag) ;

                }

                //Read the Thumbnail.
                viewTag.mThumbnailTask = new ExtractThumbnail() ;
                viewTag.mThumbnailTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, viewTag) ;

                return convertView ;
            }
        }

我创建了一个课程,当我首先点击按钮时,它会调用 Checkurl task = new Checkurl(activity, LocalFileBrowserFragment.this);

Checkurl类的代码如下(我省略了一些不重要的代码):

    public class Checkurl extends AsyncTask<URL, Integer, String>{

        Context context;
        Fragment current_frag;
        public Checkurl(Context contextin , Fragment frag)
        { 
            context = contextin;
            current_frag = frag;
            // The current_frag.getActivity here is not null
        }


        @Override
        protected String doInBackground(URL... params) {
            // TODO Auto-generated method stub
            URL url = CameraCommand.commandQueryAV1Url() ;
            if (url != null) {      
                return CameraCommand.sendRequest(url) ;
            }
            return null ;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub

        Fragment newFragment = StreamPlayerFragment.newInstance(liveStreamUrl) ;                
        FragmentManager fragmentManager = current_frag.getActivity().getFragmentManager() ;
            // But the current_frag.getActivity here is null. So it crash here.

        if (fragmentManager.getBackStackEntryCount() > 0) {

            FragmentManager.BackStackEntry backEntry = fragmentManager.getBackStackEntryAt(fragmentManager
                    .getBackStackEntryCount() - 1) ;

            if (backEntry != null && backEntry.getName().equals(newFragment.getClass().getName()))
                return ;
        }

        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction() ;

        fragmentTransaction
                .setCustomAnimations(R.anim.right_in, R.anim.right_out, R.anim.left_in, R.anim.left_out)
                .replace(R.id.mainMainFragmentLayout, newFragment)
                .addToBackStack(newFragment.getClass().getName()).commit() ;
        fragmentManager.executePendingTransactions() ;

            super.onPostExecute(result) ;
        }


    }

当ExtractThumbnail AsyncTask正在读取缩略图而不是读取完成时。 我点击按钮转到第二个片段。

致电 Checkurl task = new Checkurl(activity, LocalFileBrowserFragment.this);

但它总是在Checkurl类中的 FragmentManager fragmentManager = originalFragment.getActivity()。getFragmentManager(); 崩溃。

我尝试在日志中打印originalFragment.getActivity()。它显示originalFragment.getActivity() null

为什么originalFragment.getActivity() null

提前致谢。

3 个答案:

答案 0 :(得分:1)

您的AsyncTask应如下所示:

    Activity context;
    public Checkurl(Activity contextin){ 
        context = contextin;
    }

    protected void onPostExecute(String result) {
      //etc
      FragmentManager fragmentManager = context.getFragmentManager() ;
    }

您的来电originalFragment.getActivity()null,因为当您在后台执行任务时,您的片段与活动分离(并切换到新片段)。

此外,不要依赖AsyncTask中的当前片段,因为当您移动到新片段时它可能会被销毁(可能会导致NullPointerException)

答案 1 :(得分:1)

尝试在调用onAttach时保持活动引用,并在需要的地方使用活动引用,例如。

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mActivity = activity;
    }

答案 2 :(得分:0)

您不应该使用getActivity来检索它。覆盖片段中的void onAttach(Activity activity)并将参数的参数保存在成员变量中。