2015-07-21 20 views
0

我已在Android中实施GridView为什么片段发送到其他类后fragment.getActivity()为空?

第一个片段使用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);

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

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

为什么originalFragment.getActivity()null

在此先感谢。

+0

嗨,如果你只使用getActivity()会发生什么?无原创。 。 。 – Sheychan

+0

@Sheychan嗨,你能解释更多吗?谢谢 。 – Martin

+0

如果只使用getActivity()... no originalFragment,会发生什么情况。 – Sheychan

回答

1

AsyncTask应该是这样的:

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

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

您的通话originalFragment.getActivity()null因为你的片段从活动分离(并切换到新的片段),当你在后台做任务。

而且,不依赖于当前片段在AsyncTask因为当你移动到新的片段也可能被破坏(这可能会导致空指针异常)

0

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

1

尽量保持活性引用时onAttach被调用,使用活动在任何需要的地方参考,例如

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