我在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
?
提前致谢。
答案 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)
并将参数的参数保存在成员变量中。