2013-05-11 14 views
-1

我正在为我的Android手机编写一段代码,它将使用其personal scan在该区域创建一个WifiDevices的列表。java空指针创建Android Widgets的例外

我在创建列表时收到了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) 

这是怎么达到这个特殊的代码:

此代码调用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(); 
     } 
    } 
} 

我传递了view并再次重定向到static method因为静态方法不能使用他们的应用程序的context

我想出了问题......它说的是......只有创建视图层次结构的原始线程可以触及其视图。

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

+2

哪一行是131行?这将很大程度上决定什么是'null'。 – rgettman 2013-05-11 00:04:47

+0

空指针异常很常见。检查你的DeviceManagerWindow实例是否为空。我认为你发布的代码不是你例外的原因。告诉我们关于你的代码的更多信息将会有帮助 – Faraway 2013-05-11 00:06:40

+1

'tb'为空,因为'findViewById()'没有找到这个视图。 – 2013-05-11 00:07:21

回答

1

问题似乎是,您试图从背景Thread更新UI。您可以使用runOnUiThread(),但更容易,我认为将使ThreadAsyncTask。然后,你可以做所有的网络的东西在doInBacground()和更新UIonPostExecute()

如果这是一个单独的文件,而不是一个内部类,那么你可以只通过context的构造函数,因此你可以更新UI。或者您可以返回一个值,告诉呼叫Activity做某事或不做。我不确定,但看起来你可能会一次调用这个。如果是这样,我会建议调用一个任务,让所有的设备在后台,而UI正在做的事情,并从那里添加到列表中。另一件事是看起来您的Thread中可能有无限loopwhile true。如果是这种情况,我会将其改变为倾听价值改变的东西。希望这可以帮助

1

那么,你应该做的第一件事是调试,得到的确切位置是你的空指针异常。但是,如果你把你的代码好好看看,再就是对于具有空指针异常两个非常可能的可能性,第一个可能是:

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

因为视图V没有发现ID的任何观点= = “DEVICELIST”

或在这里:

if(device.getDeviceType()==1) 

,因为设备在你的方法获得通过 “空”。 所以,看看这两个。 好运

+0

有很多地方可以产生NPE,但只有其中一个成为由OP – codeMagic 2013-05-11 00:14:36

+0

张贴的logcat的罪魁祸首我更新了我的答案,我真的意味着这两个是最可能的... – Daniel 2013-05-11 00:23:18

+0

这是更接近,但'device.getDeviceType()'不能是问题,因为它是在与发生“NPE”的位置不同。根据logcat,错误发生在'if'块中,但是该代码位于'else'块中 – codeMagic 2013-05-11 00:25:34