App force closes with the use of runnable - java

I have to do a big task while a button click in my android app so i am using runnable to do background work. My works fine without the use of runnable but big task freezes it for a while. After the use of runnable my app is getting crashed on button click.
Here is my code for button onClick function:
public void doSearch(View v)
{
EditText et1 = (EditText) findViewById(R.id.searchText);
String query = et1.getText().toString();
Toast.makeText(this, "Searching Lyrics for "+query, Toast.LENGTH_LONG).show();
final String query1 = query.replaceAll(" ", "+");
Runnable myRunnable = new Runnable() {
#Override
public void run(){
try{
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://example.com/search.php?q="+query1);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
String line = null;
int count=0,counter=0, disCount=0;
String[] name = new String[20];
String[] link = new String[20];
String[] dis = new String[20];
while ((line = reader.readLine()) != null && counter<20){
if(count == 1){
if(line.contains("href=\"")){
line = line.substring(line.indexOf('=')+2);
link[counter] = line.substring(0, line.indexOf('"'));
line = line.substring(line.indexOf('"')+2);
name[counter] = line.substring(0, line.indexOf('<'));
}
if(disCount==1){
if(line.contains("<b>")){
line = line.replaceAll("<b>", "");
}
if(line.contains("</b>")){
line = line.replaceAll("</b>", "");
}
dis[counter] = line+"...";
counter++;
disCount=0;
}
}
if(line.equals("<div class=\"sen\">")){
count = 1;
}
if(line.equals("<div>")){
disCount=1;
}
if(line.equals("</div>")){
count = 0;
}
}
is.close();
line 82: searchResult(name, link, dis);
}catch(IOException e){} catch(IllegalStateException e){}
}
};
Thread myThread = new Thread(myRunnable);
myThread.start();
}
public void searchResult(String[] name, String[] link, String[] dis)
{
line 91: setContentView(R.layout.results);
nameTemp = name;
linkTemp = link;
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < name.length; i++) {
if(name[i]==null) break;
if(name[0]==null){
Toast.makeText(this, "Sorry! No results matched your query. \n Try again! ", Toast.LENGTH_LONG).show();
}
RowItem item = new RowItem(name[i], dis[i]);
rowItems.add(item);
}
listView = (ListView) findViewById(R.id.result);
CustomListViewAdapter adapter = new CustomListViewAdapter(this, R.layout.list_item, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(this, "Loading Lyrics for "+nameTemp[position]+"!", Toast.LENGTH_SHORT).show();
Intent i = new Intent(this, ShowLyricsActivity.class);
i.putExtra("link", linkTemp[position]);
startActivity(i);
}
Here is my logcat:
I/ActivityManager(15444): Starting activity: Intent { act=android.intent.action.MAIN flg=0x10100000 cmp=com.BoxscapeInc.SongLyrics/.MainActivity }
V/ActivityThread(28108): Reporting idle of ActivityRecord{4a2ccbe0 token=android.os.BinderProxy#4a2cc658 {com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity}} finished=false
I/WindowManager(15444): Delivering pointer 0 > Window{4a5e2508 com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity paused=false}
I/WindowManager(15444): Delivering pointer 1 > Window{4a5e2508 com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity paused=false}
I/WindowManager(15444): Dispatching key to Window{4a5e2508 com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity paused=false}
I/WindowManager(15444): Dispatching key to Window{4a5e2508 com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity paused=false}
I/WindowManager(15444): Delivering pointer 0 > Window{4a5e2508 com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity paused=false}
I/WindowManager(15444): Delivering pointer 1 > Window{4a5e2508 com.BoxscapeInc.SongLyrics/com.BoxscapeInc.SongLyrics.MainActivity paused=false}
E/AndroidRuntime(28108): at com.BoxscapeInc.SongLyrics.MainActivity.searchResult(MainActivity.java:92)
E/AndroidRuntime(28108): at com.BoxscapeInc.SongLyrics.MainActivity$100000000.run(MainActivity.java:82)
W/ActivityManager(15444): Force finishing activity com.BoxscapeInc.SongLyrics/.MainActivity
I/ActivityManager(15444): Process com.BoxscapeInc.SongLyrics (pid 28108) has died.
Somebody please help me with this error.
Any help or suggestions would be appreciated.

In Android you can modify UI components only from main thread. You are accessing components in searchResult method called from other thread.
You can do it that way:
et1.post(new Runnable() {
#Override
public void run() {
searchResult(...);
}
});
It will force you to make some variables final, so you can use them in anonymous object. It is OK. See post method.
Personally I would recommend you using AsyncTask class instead of raw Java thread. It composes running one method in background thread and running another method in main thread.

Instead of doing network calls like you have done , I suggest you use this library
you can have a look at here
http://loopj.com/android-async-http/
your code will become very very less , instead of declaring so may asynctask seperately writing bulk of code , you can just use 4 lines of code
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println(response);
}
});
It is very efficient in getting the response very quickly in 2 secs.
you don't need to use buffer reader or stuff to format the response. You can directly use the response recieved in string "response" of onSucces method.
I hope this will help you out. :)

Related

Send string from thread bluetooth service to textView in main activity

I want to send value from string (distance to obstacle) to my TextView in main activity.
I tried to use Handler, but still not working (crash) or receive nothing.
A part code which receive data from HC-05 (screen where you see in debug value assignet to variable)
enter image description here
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while(true){
try {
bytes = inputStream.read(buffer);
final String comingMsg = new String(buffer,0,bytes);
Log.d(TAG,"InputStream: " + comingMsg);
/*mHandler2.post(new Runnable() {
#Override
public void run() {
Message message = new Message();
message.obj = comingMsg;
mHandler2.sendMessage(message);
}
});*/
}catch (IOException e){
Log.e(TAG,"Write: Error reading input." + e.getMessage());
active=false;
break;
}
}
}
Here It's parts of code from MainActivity where I tried put something to get values from service.
[I add, that for this moment i want to see something values from bluetooth in textView. Later I want to create parse string and send custom text to custom TextView - example: FL: (Front Left)- to one textView, FR: (Front Right) - to second textView]
There is method implementThreads(), because I wanted to do 6 Threads to 6 TextView which every time is refreshing value from string in Services (there I tried get value from Bluetooth Service)
Log.d(TAG,"Check intent - result");
if(getIntent().getIntExtra("result",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded device");
myBluetoothService = new MyBluetoothService(getApplicationContext());
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service");
checkIfActive();
}
Log.d(TAG,"Check intent - connect_to_paired");
if(getIntent().getIntExtra("connect_to_paired",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded_paired_device");
myBluetoothService = new MyBluetoothService(getApplicationContext());
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service");
checkIfActive();
}
}
#Override
public void onStart(){
super.onStart();
myBluetoothService = new MyBluetoothService(getApplicationContext());
}
public void checkIfActive(){
Log.d(TAG,"CheckIfActive: Started");
if(myBluetoothService.active){
Log.d(TAG,"CheckIfActive: Running method implementThreads()");
implementThreads();
}
}
public void implementThreads(){
Log.d(TAG,"ImplementThreads: Started");
Thread thread = new Thread(){
#Override
public void run() {
try{
sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
};
thread.start();
}
public void startConnection(BluetoothDevice device,UUID uuid){
Log.d(TAG,"StartConnection: Initializing connection");
myBluetoothService.startClient(device,uuid);
}
Thanks all for help, because It's very important for me !
Use this to interect with UI Thread for operations like updating textviews etc.
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//YOUR CODE HERE
Message message = new Message();
message.obj = comingMsg;
mHandler2.sendMessage(message);
}
});

Android app facing null pointer exception

Here is my code
package com.example.akash.myapplication;
//Required import files here
public class MainActivity extends Activity implements Runnable
{
public TextView tex;
public Button button;
public EditText edi;
public static Socket client;
String serverName = "192.168.0.100";
int port = 4444;
protected void onCreate(Bundle savedValues) {
button= (Button) findViewById(R.id.button1);
tex= (TextView) findViewById(R.id.textView1);
edi= (EditText) findViewById(R.id.editText1);
Runnable r = new MainActivity();
final Thread t= new Thread(r);
t.start();
// Register the onClick listener with the implementation above
button.setOnClickListener(new OnClickListener() {
public void onClick(View v){
try {
t.wait();
/*System.out.println("Enter your name: ");
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
System.out.println("Connecting to " + serverName + " on port " + port);*/
client = new Socket(serverName, port);
//System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
String msg = edi.getText().toString();
out.writeUTF("Client: " + msg);
t.run();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void run()
{
while(true)
{
try
{
client = new Socket(serverName, port);
if(client.getInputStream()!=null){
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
tex.append("Server: " + in.readUTF() + "\n");}
client.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public void test(){
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
tex.setText("inside test");
/*String locationProvider = LocationManager.GPS_PROVIDER;
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
t.setText("Latitude: " + lastKnownLocation.getLatitude());*/
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
double d = location.getLatitude();
tex.setText("Latitude: " + d);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
}
And here is the null pointer error, which I guess is being caused in the run() method. I've been trying to fix this bug since more than couple hours now but all in vain.
01-07 09:05:35.178 28413-28413/com.example.akash.myapplication W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x4187fc08)
01-07 09:05:35.183 28413-28413/com.example.akash.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.akash.myapplication, PID: 28413
android.util.SuperNotCalledException: Activity {com.example.akash.myapplication/com.example.akash.myapplication.MainActivity} did not call through to super.onCreate()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
at android.app.ActivityThread.access$900(ActivityThread.java:175)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5603)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
I'd really appreciate your help people.
If possible, please share some references or guide me anyway using which I can solve these problems myself and also help others in this great community.
Thankyou in advance.
Updated, the error is smaller now after following #M D
You forget setContentView(R.layout.yourlayout); before initialized views in onCreate(...).
A lot of things in your example are very wrong.
Admittedly, not the reason for the first NPE, but let me be a prophet:
You access tex inside the run method of your runnable MainActivity.
However, tex is initialized in the onCreate method which is part of the android activity life cycle. When you call Runnable r = new MainActivity(); you create a new activity outside that lifecycle so
tex will never be initialized in that new MainActivity
even if it would run into onCreate tex would be a different view, than you'd probably expect and you would create a BufferOverflow or OutOfMemoryError because of infinitely recursive created MainActivities
If you would make your runnable an anonymous implementation inside MainActivity it would probably close over texas you would like it to.
Runnable r = new Runnable {
public void run() {
try {
client = new Socket(serverName, port);
if(client.getInputStream()!=null){
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
tex.append("Server: " + in.readUTF() + "\n");}
client.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}

audio recording and POST to server

For starters i'm an Android newbie. I have an android application that records audio for 12 seconds to a raw file and then I use lame to convert it to the final file "mezzo.mp3". The application should then upload the file to a server. However, it seems the code never executes to the upload part. Here is my code.
MainActivity.java
class UploadFileTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... voids) {
String responseString = "";
try {
String url = "http://178.62.209.46:8000/api/tag/";
File track = new File(Environment.getExternalStorageDirectory(), "mezzo.mp3");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//InputStream inputStream = new ;
reqEntity.addBinaryBody("track", track);
final HttpEntity myEntity = reqEntity.build();
httppost.setEntity(myEntity);
HttpResponse response = httpclient.execute(httppost);
//process response
responseString = new BasicResponseHandler().handleResponse(response);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
protected void onPostExecute(String responseString){
Toast.makeText(getApplicationContext(), responseString, Toast.LENGTH_LONG).show();
}
}
and here is the timer and the UploadFileTask invocation:
Button startButton = (Button) findViewById(R.id.StartButton);
startButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mRecMicToMp3.start();
CountDownTimer countDowntimer = new CountDownTimer(12000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
mRecMicToMp3.stop();
Toast.makeText(getApplicationContext(), "Stopped recording Automatically ", Toast.LENGTH_LONG).show();
}};countDowntimer.start();
}
});
new UploadFileTask().execute();
The timer runs okay and the "Stopped recording Automatically " toast shows. However, it seems new UploadFileTask().execute();never runs.
What mistake i'm I making??
You posted way to much code. You are supposed to post only relevant code. That in onClick would have been sufficient.
You have a NetworkOnMainThreadException. This will also be clearly visible in the LogCat. You have to put the 'internet code' in an AsyncTask or Thread.
Update: Hmmmm... mayby i talked to soon. Honestly i do not know if code in 'onFinish' is executed on the main thread. But if the Toast comes through it is. Please look in the LogCat for real errors.
You are starting your asynctask at the moment you install an onclicklistener. So even before the user has clicked. You should start it when the recording is done. Place that line directly after the toast that tells that the recording is stopped.

Listing of the Network Devices in Android

Similar or the same Question has been answered here
I am creating an Android App, which sends a broadcast message to the network and prepares a list of devices responding back.
Now What I did:
I created an Activity Class DeviceManagerWindow.java which calls a thread Sender.java.
Sender.java is responsible for sending the broadcast message.
Then the DeviceManagerWindow.java calls another thread which is responsible for listening to the devices responding back. The devices responding back will be listed in the Activity as soon as the device responds back. For that I have a TableLayout named deviceList.
What code I have written:
DeviceManagerWindow.java This method is called when a button for search is pressed
public void searchDevice(View v) throws IOException, InterruptedException
{
//Log.v("TableLayout:",view.toString());
sendMulticastFlyport = new Thread(new FlyportSender(MAC));
sendMulticastFlyport.start();
new Thread()
{
public void run()
{
MulticastSocket socketComputer=null;
try
{
socketComputer = new MulticastSocket(WifiConstants.COMPUTER_RECV_PORT);
socketComputer.joinGroup(InetAddress.getByName(WifiConstants.COMPUTER_NETWORK_ADDR));
socketComputer.setSoTimeout(1*60*1000);
byte[] inBufComputer = new byte[1024];
DatagramPacket inPacketComputer = new DatagramPacket(inBufComputer, inBufComputer.length);
while(true)
{
System.out.println("Listening...");
socketComputer.receive(inPacketComputer);
System.out.println("Received");
String msg = new String(inBufComputer, 0, inPacketComputer.getLength());
DeviceInformation device = new DeviceInformation(1, msg, inPacketComputer.getAddress().toString());
addDevice(device, false, 1);
Log.v("Received:","Received Computer From :" + inPacketComputer.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
{
addDevice(null, true, 1);
}
catch (IOException e1)
{
Log.v("Exception:", "Computer End Error: " +e1);
}
}
finally
{
socketComputer.close();
}
}
}.start();
The following code creates a list:
public void addDevice(DeviceInformation device, boolean bool, int type) throws IOException
{
TableLayout tb = (TableLayout) findViewById(R.id.DeviceList);
Log.v("addDevice","Called");
if(bool)
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
System.out.println(tb);
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);
}
}
else
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
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 = getApplicationContext().getResources().getDrawable(R.drawable.pc);
}
else if(device.getDeviceType()==2)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.raspberry);
}
else
{
img = getApplicationContext().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)
{
}
});
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
rowCounter++;
Log.v("Result","Device Added");
}
}
Now it is showing me an error in the logCat as:
05-11 22:01:10.165: E/AndroidRuntime(13873): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
What I have figured out from this is only the UIThread is allowed to access the Views that is created.
Previously I had tried:
new Thread()
{
public void run()
{
runOnUiThread(){
MulticastSocket socketComputer=null;
try
{
....
....
....
}
}
And that time I received an error:
Main thread cannot access Network
Before that I had tried to use synchronized methods which was called from the Receiving.java Thread File. but It also gave an error of not creating the list.
I have tried all possible ways.
Now what whould I do.?
You figured it out right. Now you can learn to either use a Handler to pass information to the UI thread (see http://www.techotopia.com/index.php/A_Basic_Overview_of_Android_Threads_and_Thread_handlers) or AsyncTask (see http://developer.android.com/reference/android/os/AsyncTask.html).
I personally prefer AsyncTask. You can paste the code which performs the search into the doInBackground() method (not need to use a separate thread, doInBackground() already does that for you) and paste the UI-related code (the list creation code) into the onPostExecute() method. Search for further examples of AsyncTask if it is not sufficiently clear how it works from the link.
EDIT: If you intend your device search code to run indefinitely, then you have to resort to Handler, as AsyncTask expects the doInBackground() method to finish before running onPostExecute(). See which option better suits your needs.

java Null Pointer Exception in creating Android Widgets

I am writing a piece of code for my Android Phone which will create a list of WifiDevices in the area using its personal scan.
I am getting java.lang.NullPointerException when I am creating a list.
My code goes follows:
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");
}
}
My Logcat error:
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)
This is how this particular code is reached:
This code calls a Thread which in return calls this method.
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());
}
}
This the code for the Thread:
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();
}
}
}
I am passing the view and the context of the application which is again redirected to the static method because static method cannot make use of them.
I figured out the problem... it is saying.. Only the original thread that created a view hierarchy can touch its views.
That is the thread (DeviceManagerWindow.java) which created the view can only access R.id.deviceList. So what should I do if I want to access it.?
The problem appears to be that you are trying to update the UI from a background Thread. You could use runOnUiThread() but even easier I think would be to make that Thread an AsyncTask. Then you can do all of the network stuff in the doInBacground() and update the UI in onPostExecute()
If this is a separate file and not an inner class then you can just pass context to the constructor so you can update the UI. Or you can return a value which tells the calling Activity to do something or not. I'm not sure but it looks like you might be calling this one at a time. If so, I would suggest calling a task to get all of the devices in the background while the UI is doing something and add them to a list from there. The other thing is it looks like you may have an infinite loop with while true in your Thread. If this is the case, I would change that to something that listens for a value to change. Hope this helps
Well, the first thing you should do is debugging, to get exactly where is your null pointer exception. But if you take a good look at your code, then there are two very probable possibilities for having a null pointer exception, the first one could be:
TableLayout tb = (TableLayout) v.findViewById(R.id.DeviceList);
because View v didn't found any view with id == "DeviceList"
or here:
if(device.getDeviceType()==1)
because device is getting passed in your method "null".
So, check out these two.
Good Luck

Categories

Resources