开发者

Null Pointer on View

开发者 https://www.devze.com 2023-02-09 20:18 出处:网络
Recently in an attempt to integrate a phone with a wireless sensor network i have adapted a class to work as an activity as well as a listener class which reads from a serial port and plots some readi

Recently in an attempt to integrate a phone with a wireless sensor network i have adapted a class to work as an activity as well as a listener class which reads from a serial port and plots some readings on to a simple canvas based View. I tried initially to construct a threaded canvas using the more normal message handlers and thread that updates and invalidates however the class that stores the readings that i need to plot was also working off a thread which listens to the USB port. I couldn't get it working at the time and i decided that i probably didn't need to constantly update the canvas given that i only need to update it with new readings.

So the activity class is as follows.

public class Oscilloscope extends Activity implements MessageListener 

Graph graph;
boolean guard=false;
MoteIF mote;
Data data;
String comm;
static String writeLog;
public Vector <Integer>  arrayvals = new Vector<Integer>();


public Oscilloscope(String comm, String writelog)
{
    this.comm = comm;
    this.writeLog = writelog;
}

public Oscilloscope()
{

}


public void onCreate(Bundle b)
{
    super.onCreate(b);
    graph = new Graph(this);
    this.setContent开发者_运维问答View(graph);
    if(guard==false)
    {
        create("dummy:1",null).run();
    }

}
synchronized public void messageReceived(int dest_addr, Message msg) {
    if (msg instanceof OscilloscopeMsg) {
        OscilloscopeMsg omsg = (OscilloscopeMsg)msg;



        periodUpdate(omsg.get_version(), omsg.get_interval());
        data.update(omsg.get_id(), omsg.get_count(), omsg.get_readings());

        List temp1 = Arrays.asList(omsg.get_readings());
        Vector<Integer> temp= new Vector<Integer>(temp1);

        this.arrayvals = temp;
        Paint p = new Paint();
        p.setColor(Color.BLUE);

        this.graph.update();
        this.graph.invalidate();

    }
}
public Oscilloscope create(String a, String b)
{
    guard = true;
    Oscilloscope os = new Oscilloscope(a,b);
    os.guard = true;
    return os;
}

Not sure why it is i cant get the code brackets working properly there, i apologise. There are other methods in the class but the class itself acts as it should minus the view part, paying particular attention to the messagereceived method where the readings are read in as array of ints. My problem is that once the onDraw method has been called once and then messagereceived is called afterwards the graph object seems to be null which obviously throws a null pointer when i try to call update. I could be not seeing something really obvious. The graph code is really simple as below:

public class Graph extends View 
    Paint paint= new Paint();
    public float x;
    public float y;
    Vector<CoOrdinate> coVec = new Vector<CoOrdinate>();

    public Graph(Context context) {
        super(context);
    }

    public void onDraw(Canvas canvas)
    {


            Log.v("Line 28 Graph.java","Y: "+y+"X: "+x);
            canvas.drawCircle(x, y, 2, paint);
            Log.v(this.toString(),"onDraw in the graph");

    }

    public void update()
    {
        Log.v("Line 31 of Graph.java","");
        x+=100;
        y+=100;
        paint.setColor(Color.GREEN);
    }
}

Any help appreciated. Thanks.

02-11 19:03:00.933: DEBUG/AndroidRuntime(301): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
02-11 19:03:00.933: DEBUG/AndroidRuntime(301): CheckJNI is ON
02-11 19:03:02.012: DEBUG/AndroidRuntime(301): --- registering native functions ---
02-11 19:03:03.942: INFO/ActivityManager(60): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=graphAndroid.graphs/.Oscilloscope }
02-11 19:03:04.062: DEBUG/AndroidRuntime(301): Shutting down VM
02-11 19:03:04.082: DEBUG/jdwp(301): adbd disconnected
02-11 19:03:04.122: INFO/AndroidRuntime(301): NOTE: attach of thread 'Binder Thread #3' failed
02-11 19:03:04.263: INFO/ActivityManager(60): Start proc graphAndroid.graphs for activity graphAndroid.graphs/.Oscilloscope: pid=308 uid=10040 gids={1015}
02-11 19:03:05.263: INFO/ARMAssembler(60): generated scanline__00000077:03545404_00000004_00000000 [ 47 ipp] (67 ins) at [0x361990:0x361a9c] in 6676000 ns
02-11 19:03:05.493: INFO/System.out(308): Creating dummy source (dummy:1)
02-11 19:03:05.493: INFO/System.out(308): No Motes:1
02-11 19:03:05.503: VERBOSE/Line 129 Oscilloscope.java(308): Made it to here
02-11 19:03:05.503: VERBOSE/Line 135 Oscilloscope.java(308): Made it here
02-11 19:03:05.513: VERBOSE/Line 137 Oscilloscope.java(308): Made it here
02-11 19:03:05.513: VERBOSE/Line 114 MoteIF.java(308): Third constructor
02-11 19:03:05.513: VERBOSE/Line 121 MoteIF.java(308): Made it here
02-11 19:03:05.513: VERBOSE/Line 123 MoteIF.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 127 MoteIF.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 130 MoteIF.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 69 PhoenixSource.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 71 PhoenixSource.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 74 PhoenixSource.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 133 MoteIF.java(308): Made it here
02-11 19:03:05.523: VERBOSE/Line 138 MoteIF.java(308): Made it here
02-11 19:03:05.533: VERBOSE/Line 140 MoteIF.java(308): Made it here
02-11 19:03:05.543: VERBOSE/Line 142 MoteIF.java(308): Made it here
02-11 19:03:05.543: VERBOSE/Line 138 Oscilloscope.java(308): Made it here
02-11 19:03:05.543: VERBOSE/Line 140 Oscilloscope.java(308): Made it to here
02-11 19:03:05.783: VERBOSE/Line 28 Graph.java(308): Y: 0.0X: 0.0
02-11 19:03:05.793: VERBOSE/graphAndroid.graphs.Graph@43e3deb8(308): onDraw in the graph
02-11 19:03:05.823: INFO/ActivityManager(60): Displayed activity graphAndroid.graphs/.Oscilloscope: 1679 ms (total 1679 ms)
02-11 19:03:07.543: INFO/System.out(308): SimulatedOscilloscopePacketSource moteId is 0
02-11 19:03:07.543: VERBOSE/1(308): A test, line 424 OscilloscopeMsg class
02-11 19:03:07.543: WARN/dalvikvm(308): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
02-11 19:03:07.563: ERROR/AndroidRuntime(308): FATAL EXCEPTION: Thread-8
02-11 19:03:07.563: ERROR/AndroidRuntime(308): java.lang.NullPointerException
02-11 19:03:07.563: ERROR/AndroidRuntime(308):     at graphAndroid.graphs.Oscilloscope.messageReceived(Oscilloscope.java:108)
02-11 19:03:07.563: ERROR/AndroidRuntime(308):     at net.tinyos.message.Receiver.packetReceived(Receiver.java:210)
02-11 19:03:07.563: ERROR/AndroidRuntime(308):     at net.tinyos.packet.PhoenixSource.dispatch(PhoenixSource.java:165)
02-11 19:03:07.563: ERROR/AndroidRuntime(308):     at net.tinyos.packet.PhoenixSource.packetDipatchLoop(PhoenixSource.java:157)
02-11 19:03:07.563: ERROR/AndroidRuntime(308):     at net.tinyos.packet.PhoenixSource.run(PhoenixSource.java:174)
02-11 19:03:07.613: WARN/ActivityManager(60):   Force finishing activity graphAndroid.graphs/.Oscilloscope
02-11 19:03:07.932: WARN/IInputConnectionWrapper(129): showStatusIcon on inactive InputConnection
02-11 19:03:08.463: INFO/ARMAssembler(60): generated scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x36b288:0x36b344] in 746000 ns


Since graph is initialized in onCreate, the graph field in the new thread will be null, as onCreate is only called for Activities. I think this is the immediate cause for the crash.

I would probably re-write the class as two classes (one Activity, one thread) to avoid confusion; but if you want to keep the same general structure, I suggest you add a second constructor for Oscilloscope that would take the Graph, and any other shared members, as parameters. Call this constructor in create, to make sure that the shared fields are passed in. (Then be very careful about synchronizing where necessary...)

EDIT: On further examination: the Graph object is passed into setContentView in onCreate. That means you must not try to use it in the other thread. Look into using MessageQueues and Handlers to post back to the UI thread, from where you can safely update the Graph.

By the way, you don't seem to save a reference to the new thread anywhere. I think that means that the new thread could be garbage-collected at any time.


When your activity is created you create another instance of it (in create(string, string)) but onCreate is never called on that new instance. So now, when messageReceived is called on that new instance, the graph object has never been instantiated and you get a null pointer exception.

0

精彩评论

暂无评论...
验证码 换一张
取 消