-1

我正在为我的 Android 手机编写一段代码,它将WifiDevices使用它的personal scan.

java.lang.NullPointerException当我创建一个列表时,我得到了。

我的代码如下:

public static synchronized void addDevice(DeviceInformation device, View v, Context con, boolean bool, int type) throws IOException {
    Log.v("addDevice", "Called");
    if (bool) {
        TableLayout tb = (TableLayout) v.findViewById(R.id.DeviceList);
        LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        TableRow tr = new TableRow(con);
        TextView tv = new TextView(con);
        System.out.println(v.toString());
        tv.setLayoutParams(layout);
        tr.setLayoutParams(layout);
        String message;
        Log.v("addDevice","Device Timeout");
        switch(type) {
            case 1:
                computerEnd = true;
                break;
            case 2:
                raspberryEnd = true;
                break;
            case 3:
                flyportEnd = true;
                break;
        }
        if (computerEnd && raspberryEnd && flyportEnd) {
            if (rowCounter > 0) {
                message = "No More Devices";
            } else {
                message = "No Devices Found"; 
            }
            tv.setText(message);
            tv.setTextColor(Color.WHITE);
            if (rowCounter % 2 == 0) {
                tr.setBackgroundColor(Color.DKGRAY);
            } else {
                tr.setBackgroundColor(Color.GRAY);
            }
            tv.setVisibility(1);
            tr.addView(tv);
            tb.addView(tr); //This is line number 131
        }
    } else {   
        TableLayout tb = (TableLayout) v.findViewById(R.id.DeviceList);
        LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        TableRow tr = new TableRow(con);
        TextView tv = new TextView(con);

        tv.setLayoutParams(layout);
        tr.setLayoutParams(layout);

        Log.v("addDevice", "Received");
        String textToDisplay = device.getDeviceTypeString() + "\n" + device.getIPAddress(); //Write the text to display
        tv.setText(textToDisplay);
        tv.setTextColor(Color.WHITE);
        Drawable img;
        if (device.getDeviceType() == 1) {
            img = con.getResources().getDrawable(R.drawable.pc);
        } else if (device.getDeviceType() == 2) {
            img = con.getResources().getDrawable(R.drawable.raspberry);
        } else {
            img = con.getResources().getDrawable(R.drawable.flyport);
        }
        img.setBounds(0,0,70,45);
        tv.setCompoundDrawables(null, null, img, null);
        tv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //empty
            }
        });
        if (rowCounter % 2 == 0) {
            tr.setBackgroundColor(Color.DKGRAY);
        } else {
            tr.setBackgroundColor(Color.GRAY);
        }
        rowCounter++;
        Log.v("Result", "Device Added");
    }
}

我的 Logcat 错误:

05-11 05:25:07.500: E/AndroidRuntime(30710): FATAL EXCEPTION: Thread-20873
05-11 05:25:07.500: E/AndroidRuntime(30710): java.lang.NullPointerException
05-11 05:25:07.500: E/AndroidRuntime(30710):    at com.example.devicecontrolpanel.DeviceManagerWindow.addDevice(DeviceManagerWindow.java:131)
05-11 05:25:07.500: E/AndroidRuntime(30710):    at com.connection.NetworkScanListenerRaspberry.run(NetworkScanListenerRaspberry.java:62)
05-11 05:25:07.500: E/AndroidRuntime(30710):    at java.lang.Thread.run(Thread.java:864)

这是达到这个特定代码的方式:

此代码调用 a Thread,而后者又调用此方法。

public void searchDevice(View view) throws IOException, InterruptedException
{
    try
    {
        Thread ComputerListener = new Thread(new NetworkScanListenerComputer(getApplicationContext(),view));
        ComputerListener.start();
    }
    catch(Exception e)
    {
        Log.v("Exception:","Exception from SearchDevice Method"+e.toString());
    }
}

这是线程的代码:

package com.connection;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

import android.content.Context;
import android.util.Log;
import android.view.View;

import com.example.devicecontrolpanel.DeviceManagerWindow;

public class NetworkScanListenerComputer implements Runnable
{
    View thisView;
    Context thisContext;
    MulticastSocket socket = null;
    DatagramPacket inPacket = null;
    byte[] inBuf;
    public NetworkScanListenerComputer(Context con, View v)
    {
        thisView = v;
        thisContext = con;
        try
        {
            socket = new MulticastSocket(WifiConstants.COMPUTER_RECV_PORT);
            socket.joinGroup(InetAddress.getByName(WifiConstants.COMPUTER_NETWORK_ADDR));
            inBuf = new byte[1024];
            inPacket = new DatagramPacket(inBuf, inBuf.length);
            socket.setSoTimeout(1*60*1000);
        }
        catch(Exception ioe)
        {
            Log.v("Exeception:","Computer Listener Exception"+ioe);
        }
    }
    @Override
    public void run()
    {
        try
        {
            while(true)
            {
                System.out.println("Listening...");
                socket.receive(inPacket);
                System.out.println("Received");
                String msg = new String(inBuf, 0, inPacket.getLength());
                DeviceInformation device = new DeviceInformation(1, msg, inPacket.getAddress().toString());

                DeviceManagerWindow.addDevice(device, thisView, thisContext, false, 1);

                Log.v("Received:","Received Computer From :" + inPacket.getAddress() + " Msg : " + msg);
                //System.out.write(inPacket.getData(),0,inPacket.getLength());
                System.out.println();
                Thread.sleep(2000);
            }
        }
        catch(Exception e)
        {
            Log.v("Exception:","During Receiving Computer: "+e.toString());
            try
            {
                DeviceManagerWindow.addDevice(null, thisView, thisContext, true, 1);
            }
            catch (IOException e1)
            {
                Log.v("Exception:", "Computer End Error: " +e1);
            }
        }
        finally
        {
            socket.close();
        }
    }
}

我正在传递应用程序的viewcontext,该应用程序再次被重定向到static method因为静态方法无法使用它们。

我发现了问题......它在说...... 只有创建视图层次结构的原始线程才能触及它的视图。

那就是创建视图的thread( DeviceManagerWindow.java)只能访问R.id.deviceList。那么如果我想访问它应该怎么做呢?

4

2 回答 2

1

好吧,您应该做的第一件事是调试,以准确了解您的空指针异常在哪里。但是,如果您仔细查看您的代码,那么有两个非常可能出现空指针异常的可能性,第一个可能是:

TableLayout tb = (TableLayout) v.findViewById(R.id.DeviceList);

因为 View v 没有找到任何 id == "DeviceList" 的视图

或在这里:

if(device.getDeviceType()==1)

因为设备正在您的方法“null”中传递。所以,看看这两个。祝你好运

于 2013-05-11T00:11:46.703 回答
1

问题似乎是您正在尝试UI从后台更新Thread。您可以使用runOnUiThread()但我认为更容易将其Thread设为AsyncTask. 然后你可以在里面做所有的网络东西并doInBacground()更新UIonPostExecute()

如果这是一个单独的文件而不是内部类,那么您可以只传递context给构造函数,以便更新UI. 或者你可以返回一个值,告诉调用Activity者是否做某事。我不确定,但看起来你可能会一次调用这个。如果是这样,我建议在UI执行某些操作时调用一个任务以在后台获取所有设备并将它们从那里添加到列表中。另一件事是看起来你loop的. 如果是这种情况,我会将其更改为侦听值更改的内容。希望这可以帮助while trueThread

于 2013-05-11T08:25:54.273 回答