【发布时间】:2014-12-26 11:57:02
【问题描述】:
我正在尝试使用 android studio 从 android 开发者网站制作自定义 android 应用程序,但我的应用程序没有在模拟器中运行它显示错误
java.lang.RuntimeException: 无法实例化活动组件信息
这是我的主要活动
package firstapp.boysjoys.com.waste;
import android.app.Activity;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by Varun on 12/24/14.
*/
public class MainActivity extends Activity {
public static final int MEDIA_TYPE_IMAGE = 1;
private Camera mcamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mcamera = getcam();
cam mcam = new cam(this, mcamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camPre);
preview.addView(mcam);
}
public static Camera getcam() {
Camera c = null;
try {
c = Camera.open();
}
catch (Exception e){
e.getMessage();
}
return c;
}
private Camera.PictureCallback mpicturecallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile=getOutPutMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile==null){
android.util.Log.d("Error","Problem");
return;
}
try {
FileOutputStream fos=new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
//CREATE A FILE URI FOR SAVING AN IMAGE OR VIDEO
private static Uri getOutPutMediaFileUri(int type){
return Uri.fromFile(getOutPutMediaFile(type));
}
private static File getOutPutMediaFile(int type){
File mediaStorage=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");
if (!mediaStorage.exists()){
if (!mediaStorage.mkdirs()) {
android.util.Log.d("Mycamera", "Failed Error");
return null;
}
}
File mediaName;
if (type==MEDIA_TYPE_IMAGE) {
mediaName = new File(mediaStorage.getPath()+File.separator+"Rim_"+".jpg");
}
else {
return null;
}
return mediaName;
}
//Button Listener to the capture button
Button btn= (Button) findViewById(R.id.Capture);
public void clickPic(View view){
mcamera.takePicture(null,null,mpicturecallback);
}
}
和相机预览活动
package firstapp.boysjoys.com.waste;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
public class cam extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mholder;
private Camera mcamera;
public cam(Context context,Camera camera){
super(context);
mholder=getHolder();
mholder.addCallback(this);
mholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* This is called immediately after the surface is first created.
* Implementations of this should start up whatever rendering code
* they desire. Note that only one thread can ever draw into
* a {@link android.view.Surface}, so you should not draw into the Surface here
* if your normal rendering will be in another thread.
*
* @param holder The SurfaceHolder whose surface is being created.
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mcamera.setPreviewDisplay(holder);
mcamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This is called immediately after any structural changes (format or
* size) have been made to the surface. You should at this point update
* the imagery in the surface. This method is always called at least
* once, after {@link #surfaceCreated}.
*
* @param holder The SurfaceHolder whose surface has changed.
* @param format The new PixelFormat of the surface.
* @param width The new width of the surface.
* @param height The new height of the surface.
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mholder.getSurface()==null) {
return;
}
mcamera.stopPreview();
//Start Preview WIth New Setting
try {
mcamera.setPreviewDisplay(mholder);
mcamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This is called immediately before a surface is being destroyed. After
* returning from this call, you should no longer try to access this
* surface. If you have a rendering thread that directly accesses
* the surface, you must ensure that thread is no longer touching the
* Surface before returning from this function.
*
* @param holder The SurfaceHolder whose surface is being destroyed.
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mholder.getSurface()!=null){
mholder.getSurface().release();
mcamera=null;
}
}
}
这是清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="firstapp.boysjoys.com.waste" >
<uses-permission android:name="android.permission.CAMERA" ></uses-permission>
<uses-permission android:name="android.permission.write_external_storage"></uses-permission>
<uses-feature android:name="android.hardware.camera2.full" android:required="false">
</uses-feature>
<uses-feature android:name="android.hardware.Camera" android:required="false"></uses-feature>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
>
<intent-filter>
<action android:name="android.intent.action.MAIN">
</action>
<category android:name="android.intent.category.LAUNCHER">
</category>
</intent-filter>
</activity>
</application>
</manifest>
这是来自 Android Studio 的完整 LogCat
12-26 15:26:46.284 610-610/firstapp.boysjoys.com.waste D/dalvikvm﹕ Not late-enabling CheckJNI (already on)
12-26 15:26:48.244 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ threadid=3: reacting to signal 3
12-26 15:26:48.434 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'
12-26 15:26:48.683 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ threadid=3: reacting to signal 3
12-26 15:26:48.754 610-610/firstapp.boysjoys.com.waste D/AndroidRuntime﹕ Shutting down VM
12-26 15:26:48.754 610-610/firstapp.boysjoys.com.waste W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
12-26 15:26:48.786 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'
12-26 15:26:48.822 610-610/firstapp.boysjoys.com.waste E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{firstapp.boysjoys.com.waste/firstapp.boysjoys.com.waste.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1880)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
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:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.app.Activity.findViewById(Activity.java:1794)
at firstapp.boysjoys.com.waste.MainActivity.<init>(MainActivity.java:102)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1319)
at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
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:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
12-26 15:26:49.154 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ threadid=3: reacting to signal 3
12-26 15:26:49.234 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'
12-26 15:26:49.654 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ threadid=3: reacting to signal 3
12-26 15:26:49.734 610-615/firstapp.boysjoys.com.waste I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'
12-26 15:27:18.314 610-610/firstapp.boysjoys.com.waste I/Process﹕ Sending signal. PID: 610 SIG: 9
我不明白它从哪里抛出 RuntimeException
在这一行,它在错误日志中显示 引起:android.app.Activity.findViewById(Activity.java:1794) 处的 java.lang.NullPointerException 说它在 xml 中返回 null 其按钮 id
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/camPre"
android:layout_weight="1"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/click"
android:text="Capture"
android:layout_gravity="center"
/>
</FrameLayout>
</LinearLayout>
我尝试调试应用程序,但仍然可以理解为什么它会抛出空指针异常 根据错误日志第 102 行,这可能是由于按钮 ID 或此行 在主要活动中
if (!mediaStorage.exists()){
if (!mediaStorage.mkdirs()) {
android.util.Log.d("Mycamera", "Failed Error");
return null;
}
}
【问题讨论】:
-
查看您的堆栈跟踪,您错过了所有重要部分,例如实际异常及其发生位置。 Runtime 只是一种异常。
-
什么是 MainActivity.java:102 行?
-
@MagicalPhoenixϡ 文件媒体名称; if (type==MEDIA_TYPE_IMAGE) { mediaName = new File(mediaStorage.getPath()+File.separator+"Rim_"+".jpg"); } 否则 { 返回空值; } 返回媒体名称;上面的行返回 mediaName 是 102