Android - 应用程序启动时片段 onCreate 崩溃
Posted
技术标签:
【中文标题】Android - 应用程序启动时片段 onCreate 崩溃【英文标题】:Android - Fragment onCreate crashes when app starts 【发布时间】:2014-10-01 01:13:39 【问题描述】:您好,我正在处理一个片段,该片段有一个按钮,允许用户选择要上传的图片。然而,当试图测试它崩溃的片段时。在它声明它崩溃的地方,如果我删除代码,那么按钮就会显示,我可以去我的画廊选择一张图片,但是一旦我点击图片,应用程序就会再次崩溃。
Logcat -
10-01 01:18:39.618 7982-7982/com.myapp.app.myapp E/androidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.myapp.app.myapp.Social.model.UserProfiles.ProfilePic.onCreate(ProfilePic.java:49)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1481)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:908)
at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:838)
at android.support.v4.app.Fragment.setUserVisibleHint(Fragment.java:843)
at android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:130)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1441)
at android.view.View.measure(View.java:15291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4819)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:15291)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:861)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:602)
at android.view.View.measure(View.java:15291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4819)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2421)
at android.view.View.measure(View.java:15291)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1867)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1111)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1292)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1009)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4242)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4941)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
at dalvik.system.NativeStart.main(Native Method)
这是片段 -
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.kii.cloud.storage.KiiObject;
import com.kii.cloud.storage.resumabletransfer.KiiRTransfer;
import com.kii.cloud.storage.resumabletransfer.KiiRTransferCallback;
import com.kii.cloud.storage.resumabletransfer.KiiUploader;
import com.myapp.app.myapp.R;
import java.io.File;
import java.io.FileOutputStream;
public class ProfilePic extends Fragment
private static final String TAG = "ProfilePic";
String objectUri = null;
private static final int PICK_IMAGE = 1;
private Activity activity;
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_attach_file, container,
false);
return view;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
objectUri = getArguments().getString("object_uri");
Button attachButton = (Button)
getView().findViewById(R.id.attach_file_button);
attachButton.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
onAttachFileButtonClicked(v);
);
setPageImage(3);
ImageView imageView = (ImageView) getView().findViewById(R.id.details);
imageView.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
);
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
this.activity = activity;
@Override
public void onDetach()
super.onDetach();
this.activity = null;
public void onAttachFileButtonClicked(View v)
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK)
Uri selectedFileUri = data.getData();
String filePath = getFilePathByUri(selectedFileUri);
Log.v(TAG, "Picture Path : " + filePath);
if (filePath == null)
showAlert("File not exists, Please select an image that exists locally.");
return;
uploadFile(filePath);
else
showToast("picking file failed!");
private void showToast(String message)
Toast.makeText(this.activity, message, Toast.LENGTH_SHORT).show();
private String getFilePathByUri(Uri selectedFileUri)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
// Workaround of retrieving file image through ContentResolver
// for Android4.2 or later
String filePath = null;
FileOutputStream fos = null;
try
Bitmap bmp = MediaStore.Images.Media.getBitmap(
this.activity.getContentResolver(), selectedFileUri);
String cacheDir = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "app";
File createDir = new File(cacheDir);
if (!createDir.exists())
createDir.mkdir();
filePath = cacheDir + File.separator + "upload.jpg";
File file = new File(filePath);
fos = new FileOutputStream(file);
bmp.compress(CompressFormat.JPEG, 95, fos);
fos.flush();
fos.getFD().sync();
catch (Exception e)
filePath = null;
finally
if (fos != null)
try
fos.close();
catch (Exception e)
// Nothing to do
return filePath;
else
String[] filePathColumn = MediaStore.MediaColumns.DATA ;
Cursor cursor = this.activity.getContentResolver().query(
selectedFileUri, filePathColumn, null, null, null);
if (cursor == null)
return null;
try
if (!cursor.moveToFirst())
return null;
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (columnIndex < 0)
return null;
String picturePath = cursor.getString(columnIndex);
return picturePath;
finally
cursor.close();
private void uploadFile(String path)
KiiObject object = KiiObject.createByUri(Uri.parse(objectUri));
File f = new File(path);
Log.v(TAG, "file can read : " + f.canRead());
KiiUploader uploader = object.uploader(this.activity, f);
uploader.transferAsync(new KiiRTransferCallback()
@Override
public void onStart(KiiRTransfer operator)
setFragmentProgress(View.VISIBLE);
@Override
public void onTransferCompleted(KiiRTransfer operator, Exception e)
setFragmentProgress(View.INVISIBLE);
if (e == null)
else
);
public void moveFromDialogFragment(Class<?> clazz)
if (clazz != null)
Intent i = new Intent(this.activity, clazz);
startActivity(i);
void showAlert(String message)
DialogFragment newFragment = AlertDialogFragment.newInstance(
R.string.operation_failed, message, null);
newFragment.show(getFragmentManager(), "dialog");
void setFragmentProgress(int v)
ProgressFragment fragment = (ProgressFragment) getFragmentManager()
.findFragmentById(R.id.progressFragment);
if (fragment != null && fragment.isInLayout())
fragment.setProgressBarVisiblity(v);
void setPageImage(int page)
ProgressFragment fragment = (ProgressFragment) getFragmentManager()
.findFragmentById(R.id.progressFragment);
if (fragment != null && fragment.isInLayout())
fragment.setPageImage(page);
任何其他需要帮助的代码请告诉我。
更新 我尝试了这些建议,但我仍然收到同样的错误。它似乎在 -
objectUri = args.getString("object_uri");
更新 2 我尝试了建议的代码,但仍然在同一行收到相同的错误。我更新了我的代码和 logcat 以反映所做的更改。
谢谢
【问题讨论】:
【参考方案1】:onCreateView()
返回的视图被设置为片段的根视图。使用 Fragment 类的getView()
方法代替onActivityCreated()
中的view
。
更新
在 Fragment 生命周期中,添加 Fragment 时,回调方法会按规则顺序调用。 onAttach() -> onCreate() -> onCreateView() -> onActivityCreated()。
onCreateView() 实例化片段的视图,并将视图设置为根视图。你的代码是正确的。但是,onCreate() 在 onCreateView() 之前被调用。片段的根视图尚未在 onCreate() 中设置。您不能在 onCreate() 中使用 getView() 方法。它将返回 null。
我建议您使用 onActivityCreated() 而不是 onCreate() 来访问片段的视图。
改变
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
到
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
【讨论】:
我将如何使用 getview? 在 Fragment 扩展类中这样使用即可。Button attachButton = (Button) getView().findViewById(R.id.attach_file_button);
好吧,这就是我的想法。我试过了,但仍然收到错误。检查我的问题以了解我的更新
让我知道如何在父活动中为您的ProfilePic
片段设置参数。
对不起,我的错误。请忽略此答案中的上述评论。我误解了您在代码中使用了onActivityCreated()
方法。我将更新我的答案。【参考方案2】:
我发现
Button attachButton = (Button) view.findViewById(R.id.attach_file_button);
view
未初始化。我认为findViewById()
应该放在onCreateView()
中。
【讨论】:
我搬了还是一样的问题【参考方案3】:改变
View view = inflater.inflate(R.layout.fragment_attach_file, container,false);
到
view = inflater.inflate(R.layout.fragment_attach_file, container,false);
你不需要再次声明它,因为它已经在你班级的private View view;
声明了。当你在你的方法中再次声明它时,它会将赋值给自己,所以你的成员变量为空。
Shadowing
更新
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
objectUri = getArguments().getString("object_uri");
更新 2
你没有为你的片段设置任何参数并且它是空的。
在这一行Button attachButton=(Button)getView().findViewById(R.id.attach_file_button);
也getView
返回null
因为onCreate
在onCreateView
之前被调用
【讨论】:
如果我删除第二个视图,它会在第一个表示预期表达式的情况下给出错误。 我不明白你的意思,请详细说明! 好的,我应该删除 oncreate 视图还是 activitycreated? 你没有为你的片段设置任何参数,它是空的。Button attachButton = (Button) getView().findViewById(R.id.attach_file_button);
and 还有getView
返回null,因为onCreate
在onCreateView
之前被调用以上是关于Android - 应用程序启动时片段 onCreate 崩溃的主要内容,如果未能解决你的问题,请参考以下文章