Android使用带线程的自定义视图

时间:2015-02-03 06:29:10

标签: android

我想做的就像下面的

enter image description here

camera.xml中的customViewContainer将保存自定义的myView。

如果我选择拍照(R.id.capture),那么我可以立即拍照并且该照片会显示在右侧。

如果我选择获取图片(R.id.process),那么我可以从图库中获取图片,并且该图片也将显示在右侧。

在右侧,会有一个小的矩形物体(20像素,20像素),它是透明的,它会被照片上的用户触摸移动。

问题是......当我单独制作这些功能时,它们工作正常但是当我将它们组合在一起时,活动无法启动。

您是否会查看我的代码并查看问题所在?我将非常感激。 < 1 + _ + ;;>>

package com.example.hello;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.PorterDuff.Mode;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Images;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class SurfaceViewExample extends Activity implements OnTouchListener     
{

    OurView v;
    float x = 0;
    float y = 0;
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
         R.drawable.default_background);
         //default_background picture is for the first screen.

    private static final int CAMERA_CAPTURE = 0;
    final static int SELECT_IMAGE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setContentView(R.layout.camera);

        v = new OurView(this);
        v.setOnTouchListener(this);
        LinearLayout customViewContainer =
             (LinearLayout)findViewById(R.id.customViewContainer);
        customViewContainer.addView(v);

        Button captureButton = (Button) findViewById(R.id.capture);
        Button processButton = (Button) findViewById(R.id.process);

        captureButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent i = new Intent(
                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
                    Uri.fromFile(new File("/sdcard/image.jpg")));
                startActivityForResult(i, CAMERA_CAPTURE);
            }
        });

        processButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) { Uri uri =  
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            Intent intent = new Intent(Intent.ACTION_PICK, uri);
            startActivityForResult(intent, SELECT_IMAGE);
            }
        });
    }   

    //onActivityResult is for getting picture
    @Override
    protected void onActivityResult(int requestCode, int resultCode, 
        Intent intent) 
    {

        if (resultCode == RESULT_OK && (requestCode == (CAMERA_CAPTURE) ||
             requestCode == SELECT_IMAGE)) {

            if(requestCode == CAMERA_CAPTURE)
            {
                File file = new File("/sdcard/image.jpg");
                try {
                    bitmap = Images.Media.getBitmap(getContentResolver(),
                    Uri.fromFile(file));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            else if(requestCode == SELECT_IMAGE)
            {
                Uri image = intent.getData();
                try {
                    bitmap = Images.Media.getBitmap(getContentResolver(),
                    image);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //for custom made resume and pause function
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        v.resume();
    }

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

    //This is the custom made view which uses thread
    protected class OurView extends SurfaceView implements Runnable {

        Thread t = null;
        SurfaceHolder holder;
        boolean isItOk = false;

        public OurView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            holder = getHolder();
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(isItOk == true) 
            {
                //perform canvas drawing
                if(!holder.getSurface().isValid())
                {
                    continue; //make is work when it is valid
                }

                Canvas c = holder.lockCanvas();
                Rect ourRect = new Rect();
                ourRect.set((int)x, (int)y, (int)x+20, (int)y+20);
                Paint rect_paint = new Paint();
                c.drawColor(Color.TRANSPARENT, Mode.CLEAR);
                rect_paint.setStyle(Paint.Style.STROKE);
                rect_paint.setColor(Color.BLUE);
                c.drawBitmap(bitmap, c.getWidth()/2 - bitmap.getWidth()/2,      
                   c.getHeight()/2 - bitmap.getHeight()/2 ,null);
                c.drawRect(ourRect, rect_paint);
                holder.unlockCanvasAndPost(c);              
            }
        }

        public void pause() {
            isItOk = false;
            while(true) {
                try{
                    t.join();
                }catch ( InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            }
            t = null;
        }

        public void resume() {
            isItOk = true;
            t = new Thread(this);
            t.start();
        }   
    }

    @Override
    public boolean onTouch(View v, MotionEvent me) {
        // TODO Auto-generated method stub

        try {
            Thread.sleep(50); //To protect program from working too much
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        switch(me.getAction()) 
        {
        case MotionEvent.ACTION_DOWN:
            x = me.getX()-10;
            y = me.getY()-10;
            break;

        case MotionEvent.ACTION_UP:
            x = me.getX()-10;
            y = me.getY()-10;
            break;

        case MotionEvent.ACTION_MOVE:
            x = me.getX()-10;
            y = me.getY()-10;
            break;
        }
        return true;
    }

}

以防万一,我在下面留下了camera.xml和logcat信息,但我认为这是代码问题而不是系统......

camera.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_weight="3"
        android:layout_margin="30dp" >

        <Button
            android:id="@+id/capture"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:layout_marginBottom="10dp"
            android:text="Taking Picture" />

        <Button
            android:id="@+id/process"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:text="Getting Picture" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/customViewContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:orientation="vertical"/>

</LinearLayout>

02-03 14:52:34.895: D/AndroidRuntime(2310): Shutting down VM
02-03 14:52:34.895: W/dalvikvm(2310): threadid=1: thread exiting with uncaught exception (group=0xa6221908)
02-03 14:52:34.895: E/AndroidRuntime(2310): FATAL EXCEPTION: main
02-03 14:52:34.895: E/AndroidRuntime(2310): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.hello/com.example.hello.SurfaceViewExample}: java.lang.NullPointerException
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.os.Looper.loop(Looper.java:137)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.main(ActivityThread.java:5041)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.reflect.Method.invokeNative(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.reflect.Method.invoke(Method.java:511)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-03 14:52:34.895: E/AndroidRuntime(2310): at dalvik.system.NativeStart.main(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): Caused by: java.lang.NullPointerException
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:78)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.example.hello.SurfaceViewExample.<init>(SurfaceViewExample.java:37)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.Class.newInstanceImpl(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.Class.newInstance(Class.java:1319)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
02-03 14:52:34.895: E/AndroidRuntime(2310): ... 11 more
02-03 14:52:34.895: D/AndroidRuntime(2310): Shutting down VM
02-03 14:52:34.895: W/dalvikvm(2310): threadid=1: thread exiting with uncaught exception (group=0xa6221908)
02-03 14:52:34.895: E/AndroidRuntime(2310): FATAL EXCEPTION: main
02-03 14:52:34.895: E/AndroidRuntime(2310): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.hello/com.example.hello.SurfaceViewExample}: java.lang.NullPointerException
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.os.Looper.loop(Looper.java:137)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.main(ActivityThread.java:5041)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.reflect.Method.invokeNative(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.reflect.Method.invoke(Method.java:511)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-03 14:52:34.895: E/AndroidRuntime(2310): at dalvik.system.NativeStart.main(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): Caused by: java.lang.NullPointerException
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:78)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.example.hello.SurfaceViewExample.<init>(SurfaceViewExample.java:37)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.Class.newInstanceImpl(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.Class.newInstance(Class.java:1319)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
02-03 14:52:34.895: E/AndroidRuntime(2310): ... 11 more
02-03 14:52:34.895: D/AndroidRuntime(2310): Shutting down VM
02-03 14:52:34.895: W/dalvikvm(2310): thread id=1: thread exiting with uncaught exception (group=0xa6221908)
02-03 14:52:34.895: E/AndroidRuntime(2310): FATAL EXCEPTION: main
02-03 14:52:34.895: E/AndroidRuntime(2310): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.hello/com.example.hello.SurfaceViewExample}: java.lang.NullPointerException
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.os.Looper.loop(Looper.java:137)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.main(ActivityThread.java:5041)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.reflect.Method.invokeNative(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.reflect.Method.invoke(Method.java:511)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-03 14:52:34.895: E/AndroidRuntime(2310): at dalvik.system.NativeStart.main(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): Caused by: java.lang.NullPointerException
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:78)
02-03 14:52:34.895: E/AndroidRuntime(2310): at com.example.hello.SurfaceViewExample.<init>(SurfaceViewExample.java:37)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.Class.newInstanceImpl(Native Method)
02-03 14:52:34.895: E/AndroidRuntime(2310): at java.lang.Class.newInstance(Class.java:1319)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
02-03 14:52:34.895: E/AndroidRuntime(2310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
02-03 14:52:34.895: E/AndroidRuntime(2310): ... 11 more

1 个答案:

答案 0 :(得分:1)

与日志一样:

  

引起:java.lang.NullPointerException 02-03 14:52:34.895:   E / AndroidRuntime(2310):在android.content.ContextWrapper.getResources

表示您尝试使用getResources的上下文访问null方法。

从Activity的onCreate方法调用getResources()方法:

Bitmap bitmap; 
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setContentView(R.layout.camera);
        bitmap = BitmapFactory.decodeResource(getResources(),
                                R.drawable.default_background);
        ....