I am getting this exception. When, i'm trying to run my program. In my program i am executing an AsyncTask For each download and upload tasks, I have created new AsyncTask object and tried to run it in background. I tried to find my mistake. But i can't find where i am going wrong. Below are my stack trace and code of my program -
05-07 10:00:44.899: E/AndroidRuntime(367): FATAL EXCEPTION: AsyncTask #1
05-07 10:00:44.899: E/AndroidRuntime(367): java.lang.RuntimeException: An error occured while executing doInBackground()
05-07 10:00:44.899: E/AndroidRuntime(367): at android.os.AsyncTask$3.done(AsyncTask.java:200)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.lang.Thread.run(Thread.java:1019)
05-07 10:00:44.899: E/AndroidRuntime(367): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-07 10:00:44.899: E/AndroidRuntime(367): at android.os.Handler.<init>(Handler.java:121)
05-07 10:00:44.899: E/AndroidRuntime(367): at android.widget.Toast.<init>(Toast.java:68)
05-07 10:00:44.899: E/AndroidRuntime(367): at android.widget.Toast.makeText(Toast.java:231)
05-07 10:00:44.899: E/AndroidRuntime(367): at com.android.test.Helper.downloadTask(t.java:269)
05-07 10:00:44.899: E/AndroidRuntime(367): at com.android.test.Helper.doInBackground(t.java:132)
05-07 10:00:44.899: E/AndroidRuntime(367): at com.android.test.Helper.doInBackground(t.java:1)
05-07 10:00:44.899: E/AndroidRuntime(367): at android.os.AsyncTask$2.call(AsyncTask.java:185)
05-07 10:00:44.899: E/AndroidRuntime(367): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
05-07 10:00:44.899: E/AndroidRuntime(367): ... 4 more
This is my AsynTask Helper
class Helper extends AsyncTask<Integer, Void, Void>
{
private SmbFile dfile;
private String dfilepath;
private SmbFile dfolder;
private String dfolderpath;
private File ufolder;
private SmbFile ufoldersmb;
private NtlmPasswordAuthentication auth;
private int upstate=0;
private int downstate=0;
private Context context;
private ArrayList<SmbFile> smbArray=new ArrayList<SmbFile>();
private String ext;
private int tasknumber;
private String taskname;
public Context getcontext()
{
return context;
}
public int gettasknumber()
{
return tasknumber;
}
public String gettaskname()
{
return taskname;
}
public int getupstate()
{
return upstate;
}
public int getdownstate()
{
return downstate;
}
public void setdfile(SmbFile a)
{
this.dfile = a;
}
public void setdfilepath(String b)
{
this.dfilepath = b;
}
public void setdfolder(SmbFile c)
{
this.dfolder = c;
}
public void setdfolderpath(String d)
{
this.dfolderpath = d;
}
public void setufolder(File g)
{
this.ufolder = g;
}
public void setufoldersmb(SmbFile h)
{
this.ufoldersmb = h;
}
public void setauthentication(NtlmPasswordAuthentication i)
{
this.auth = i;
}
public void setupstate(int j)
{
upstate = j;
}
public void setdownstate(int k)
{
downstate = k;
}
public void setcontext(Context l)
{
context = l;
}
public void setarraysmb(SmbFile m)
{
this.smbArray.add(m);
}
public void setextstorage(String n)
{
this.ext=n;
}
public void settasknumber(int o)
{
this.tasknumber=o;
}
public void settaskname(String p)
{
this.taskname=p;
}
#Override
protected Void doInBackground(Integer... params)
{
//check flag to execute exactly method
switch (params[0])
{
case 0:
downloadTask();
break;
case 1:
Toast.makeText(context, "AccessPC Upload task "+tasknumber+" Started", Toast.LENGTH_LONG).show();
uploadFolder(ufolder,ufoldersmb);
break;
default:break;
}
return null;
}
void downloadFile(SmbFile dfile,String dpath)
{
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
long blockSize = statFs.getBlockSize();
long freeSize = statFs.getFreeBlocks()*blockSize;
try
{
if(!((freeSize-dfile.length())<0))
{
SmbFileInputStream din=new SmbFileInputStream(dfile);
FileOutputStream dout=new FileOutputStream(dpath);
int c;
while((c=din.read())!=-1)
{
dout.write(c);
}
if (din != null)
{
din.close();
}
if (dout != null)
{
dout.close();
}
}
else
{
Toast.makeText(context, "AccessPC Download Task failed ",Toast.LENGTH_LONG).show();
}
}
catch(Exception e)
{
Toast.makeText(context, "AccessPC Download Task failed "+e,Toast.LENGTH_LONG).show();
}
}
void downloadFolder(SmbFile dfolder,String dfolderpath)
{
try
{
dfolderpath=dfolderpath+dfolder.getName();
if(!(new File(dfolderpath)).exists())
{
(new File(dfolderpath)).mkdir();
}
SmbFile[] temp=dfolder.listFiles();
if(temp.length==0)
{
Toast.makeText(context, "df,downstate="+downstate,Toast.LENGTH_LONG).show();
return;
}
for(SmbFile m:temp)
{
if(m.isFile())
{
downloadFile(m,dfolderpath+m.getName());
}
else
{
downloadFolder(m,dfolderpath);
}
}
}
catch (Exception e)
{
Toast.makeText(context, "AccessPC Download Task failed "+e,Toast.LENGTH_LONG).show();
}
}
void uploadFile(File ufile,SmbFile ufilesmb)
{
try
{
FileInputStream uin=new FileInputStream(ufile);
SmbFile tempSmb=new SmbFile(ufilesmb.getPath()+ufile.getName(),auth);
SmbFileOutputStream uout=new SmbFileOutputStream(tempSmb);
int c;
while((c=uin.read())!=-1)
{
uout.write(c);
}
if (uin != null)
{
uin.close();
}
if (uout != null)
{
uout.close();
}
}
catch(Exception e)
{
Toast.makeText(context, "AccessPC Upload Task failed "+e, Toast.LENGTH_LONG).show();
}
}
void uploadFolder(File ufolder,SmbFile ufoldersmb)
{
try
{
SmbFile tempSmb=new SmbFile(ufoldersmb.getPath()+ufolder.getName()+"/",auth);
if(!tempSmb.exists())
{
tempSmb.mkdir();
}
File[] ftemp=ufolder.listFiles();
if(ftemp.length==0)
{
setupstate(2);
return;
}
for(File m:ftemp)
{
if(m.isFile())
{
uploadFile(m,tempSmb);
}
else
{
uploadFolder(m,tempSmb);
}
}
}
catch (Exception e)
{
Toast.makeText(context, "AccessPC Upload Task failed "+e,Toast.LENGTH_LONG).show();
}
}
void downloadTask()
{
Toast.makeText(context, "AccessPC download task "+tasknumber+" Started", Toast.LENGTH_LONG).show();
try
{
for(SmbFile m:smbArray)
{
if(m.isFile())
{
setdfile(m);
setdfilepath(ext+m.getName());
downloadFile(dfile,dfilepath);
}
else
{
setdfolder(m);
setdfolderpath(ext);
downloadFolder(dfolder,dfolderpath);
}
}
setdownstate(2);
}
catch (Exception e)
{
Toast.makeText(context,"Download error "+e,Toast.LENGTH_LONG).show();
}
}
#Override
protected void onPostExecute(Void result)
{
if(upstate==2)
{
setupstate(0);
Toast.makeText(context, "AccessPC "+taskname+" task "+tasknumber+" Finished", Toast.LENGTH_LONG).show();
}
if(downstate==2)
{
setdownstate(0);
Toast.makeText(context, "AccessPC "+taskname+" task "+tasknumber+" Finished", Toast.LENGTH_LONG).show();
}
}
}
This is my options menu. I ve used this to do my asyn task
variable i have used in my main activity which helps this task:
String extStorage=Environment.getExternalStorageDirectory()+"/t/";
ArrayList<Helper> helpobject=new ArrayList<Helper>();
int uptask=0;
int downtask=0;
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case DOWNLOAD1:
MENU_STATE=MENU_DOWNLOAD;
map=display_check(current);
return true;
case UPLOAD:
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
if(current.getShare()==null)
{
Toast.makeText(this,"UPLOAD FAILED",Toast.LENGTH_LONG).show();
}
else
{
File f=new File(extStorage);
Helper help=new Helper();
help.setufolder(f);
help.setufoldersmb(current);
help.setauthentication(auth);
help.setupstate(1);
help.settasknumber(uptask);
uptask++;
help.settaskname("Upload");
help.setcontext(this.getApplicationContext());
help.execute(1);
}
}
else
{
Toast.makeText(this,"UPLOAD FAILED--NO SD CARD FOUND",Toast.LENGTH_LONG).show();
}
return true;
case DELETE1:
MENU_STATE=MENU_DELETE;
map=display_check(current);
return true;
case QUIT:
int x=0;
for(Helper k:helpobject)
{
if(k.getStatus().equals(AsyncTask.Status.RUNNING)||k.getStatus().equals(AsyncTask.Status.RUNNING))
{
Toast.makeText(k.getcontext(), "AccessPC "+k.gettaskname()+" "+k.gettasknumber()+" Cancelled", Toast.LENGTH_SHORT).show();
k.cancel(true);
}
helpobject.remove(x);
x++;
}
return true;
case DOWNLOAD2:
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
int tempcount=0;
for(int i=0;i<object.getCount();i++)
{
if(object.getter(i)==true)
{
tempcount++;
}
}
if(tempcount==0)
{
Toast.makeText(this,"Please choose atleast one item for download!!",Toast.LENGTH_LONG).show();
}
else
{
Helper help=new Helper();
helpobject.add(help);
help.settasknumber(downtask);
downtask++;
help.settaskname("Download");
help.setcontext(this.getApplicationContext());
help.setextstorage(extStorage);
help.setdownstate(1);
for(int i=0;i<object.getCount();i++)
{
if(object.getter(i)==true)
{
help.setarraysmb(map.get(object.getItem(i)));
}
}
help.execute(0);
}
}
else
{
Toast.makeText(this,"DOWNLOAD FAILED--NO SD CARD FOUND",Toast.LENGTH_LONG).show();
}
return true;
case DELETE2:
for(int i=0;i<object.getCount();i++)
{
if(object.getter(i)==true)
{
try
{
map.get(object.getItem(i)).delete();
}
catch (Exception e)
{
Toast.makeText(this,"cannot be deleted "+e,Toast.LENGTH_LONG).show();
}
}
}
return true;
case CANCEL:
MENU_STATE=MENU_GENERAL;
map=display(current);
return true;
case FINISH:
finish();
default:
return super.onOptionsItemSelected(item);
}
}
hi,when i tried to display the toast, as mentioned in one of the below comments, ive got the same exception .please see the code below whih i ve used to dispaly Toast in my async task:
(new Activity()).runOnUiThread(new Runnable(){#Override public void run() {//Your Toast
Toast.makeText(context, "AccessPC Download Task failed ",Toast.LENGTH_LONG).show();
}});
Do i need to make any changes to my async task code or options menu code?
I ve used handler like this:
public Handler handler = new Handler() {
public void handleMessage(Message msg)
{
Bundle b = msg.getData();
String key = b.getString(null);
Toast.makeText(getApplicationContext(),key, Toast.LENGTH_SHORT).show();
}
};
and i am calling handler like this:
Message msg = new Message();
Bundle b = new Bundle();
b.putString(null, "AccessPC "+taskname+" task "+tasknumber+" Finished");
msg.setData(b);
//this is error
t.handler.sendMessage(msg);
But how can i call a non-static method?do i need to create an object for my main class(class t extends list activity)?
Hi, please see another exception that ive got when i select 'QUIT' operation from options menu for the above async task and menu ive posted. how to avoid this exception:
05-07 16:24:07.573: E/AndroidRuntime(13466): FATAL EXCEPTION: main
05-07 16:24:07.573: E/AndroidRuntime(13466): java.util.ConcurrentModificationException
05-07 16:24:07.573: E/AndroidRuntime(13466): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.test.t.onOptionsItemSelected(t.java:622)
05-07 16:24:07.573: E/AndroidRuntime(13466): at android.app.Activity.onMenuItemSelected(Activity.java:2205)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:748)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:143)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:855)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.view.menu.IconMenuView.invokeItem(IconMenuView.java:532)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.view.menu.IconMenuItemView.performClick(IconMenuItemView.java:122)
05-07 16:24:07.573: E/AndroidRuntime(13466): at android.view.View$PerformClick.run(View.java:9080)
05-07 16:24:07.573: E/AndroidRuntime(13466): at android.os.Handler.handleCallback(Handler.java:587)
05-07 16:24:07.573: E/AndroidRuntime(13466): at android.os.Handler.dispatchMessage(Handler.java:92)
05-07 16:24:07.573: E/AndroidRuntime(13466): at android.os.Looper.loop(Looper.java:123)
05-07 16:24:07.573: E/AndroidRuntime(13466): at android.app.ActivityThread.main(ActivityThread.java:3683)
05-07 16:24:07.573: E/AndroidRuntime(13466): at java.lang.reflect.Method.invokeNative(Native Method)
05-07 16:24:07.573: E/AndroidRuntime(13466): at java.lang.reflect.Method.invoke(Method.java:507)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-07 16:24:07.573: E/AndroidRuntime(13466): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-07 16:24:07.573: E/AndroidRuntime(13466): at dalvik.system.NativeStart.main(Native Method)
Can't create handler inside thread that has not called Looper.prepare(), the error message is rather straightforward.
You created a Handler object in your AsyncTask.doInBackground()(a background thread), which requires a message pump in that thread, that's the Looper.prepare() thing.
I think it may be easier to just move the creation of your Handler object out of AysncTask, to the UI thread.
Below is the edit after the OP edited his/her question
Toast.makeText(context, "AccessPC Upload task "+tasknumber+" Started", Toast.LENGTH_LONG).show();
The line above is simply not allowed in a background thread, showing a Toast message is something updating the UI, which must happen in the UI thread.
EDIT again
You can use a Handler, which is created in the UI thread, to send a message, and in the Handler, handle that message by showing your desired Toast message.
EDIT again 2
private final static int TOAST_MSG_ID_1 = 1;
private final static int TOAST_MSG_ID_2 = 2;
private final static int TOAST_MSG_ID_3 = 3;
// declare a Handler as an instance variable
Handler msgHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
switch(msg.what()) {
case TOAST_MSG_ID_1:
Toast.makeText(...msg1...).show();
break;
case TOAST_MSG_ID_2:
Toast.makeText(...msg2...).show();
break;
.... other messages follow....
}
}
};
// and you will use the following to show a Toast message:
msgHandler.sendEmptyMessage(TOAST_MSG_ID_1);
msgHandler.sendEmptyMessage(TOAST_MSG_ID_2);
msgHandler.sendEmptyMessage(TOAST_MSG_ID_3);
...
For more info about Handler, take a look at the javadoc first. and google will bring you more.
write Toast message as below I hope it will work.
getApplicationContext().runOnUiThread(new Runnable() {
#Override
public void run() {
//Your Toast
}
});
Comment your all Toast message which you are showing using with Non-UI thread. I think this the problem..
Related
I am closing an activity via finish().
It works fine on several devices but on a Samsung Galaxy S3 Neo running Android 4.4 I get the following issue:
java.lang.RuntimeException
android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3706)
android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3724)
android.app.ActivityThread.access$1500(ActivityThread.java:169)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:136)
android.app.ActivityThread.main(ActivityThread.java:5476)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:515)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
dalvik.system.NativeStart.main(Native Method)
Caused by: android.util.Log.println_native(Native Method)
android.util.Log.e(Log.java:307)
com.ads.adstimer.fragment.Registration.RegistrationActivity.onDestroy(RegistrationActivity.java:214)
android.app.Activity.performDestroy(Activity.java:5623)
android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1123)
android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3693)
android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3724)
android.app.ActivityThread.access$1500(ActivityThread.java:169)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:136)
android.app.ActivityThread.main(ActivityThread.java:5476)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:515)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
dalvik.system.NativeStart.main(Native Method)
I have found two posts about that subject: First, Second
But they did not help me.
My activity code. Note that I am using AppIntro:
public class RegistrationActivity extends AppIntro {
private AsyncTaskRegisterInBackground registerPushToken;
(...)
#Override
public void onDonePressed() {
(...)
if (regid.isEmpty()) {
registerPushToken = new AsyncTaskRegisterInBackground();
registerPushToken.setParams(activity, gcm, regid);
registerPushToken.execute();
}
(...)
}
#Override
public void onTaskCompleted(String responseRegid) {
try {
// load authToken from Server: JsonObjectRequest
builderOnFailureDialog = new MaterialDialog.Builder(activity)
.title(getResources().getString(R.string.registrierung_dialog_registrieren_failure_retry_title))
.content(onFailureDialogContent)
.positiveText(getResources().getString(R.string.registrierung_dialog_registrieren_failure_retry_positive_text))
.negativeText(getResources().getString(R.string.registrierung_dialog_registrieren_failure_retry_negative_text))
.onNegative(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
activity.finish();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
onFailureDialog.dismiss();
onSuccessDialog.dismiss();
} catch (Exception e) {
Log.e("Activity.onDestroy()", e.getMessage());
}
}
}
Or is the reason for the problem the async task running in background?
call finish() inside runOnUiThread().
i.e.
replace
finish();
with
runOnUiThread(new Runnable() {
public void run() {
finish()
}
});
i m new in android and trying to make simple program that can print variable in AsyncTask Class
here is my code
int a,b,c;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
a =10;
b=10;
c=a+b;
Context ctx = null;
show(c, ctx );
return null;
}
public void show(int c2 ,Context c) {
// TODO Auto-generated method stub
Toast.makeText(c, "AsyncTask classs + c2 ", Toast.LENGTH_SHORT).show();
}
after running this program , i m getting run time Error
here us LogCat file view
Process: com.example.asycclass, PID: 2539
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:327)
at android.widget.Toast.<init>(Toast.java:92)
at android.widget.Toast.makeText(Toast.java:241)
at com.example.asycclass.MainActivity$AttemptLogin.show(MainActivity.java:74)
at com.example.asycclass.MainActivity$AttemptLogin.doInBackground(MainActivity.java:65)
at com.example.asycclass.MainActivity$AttemptLogin.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
Move your show Toast code inside runOnUiThread like :
runOnUiThread(new Runnable() {
#Override
public void run() {
show(c, ctx );
}
});
I guess that the problem is that you're trying to create a Toast not from the main thread.
You must create a handler and Runnable for that and use handler.post()
For example
Runnable showToast = new Runnable() {
public void run() {
// Create your Toast here or whatever you want
}
}
I'm developing an app with eclipse and arduino which connects to a bluetooth module. I can then control the LEDS on the board. However my code shows no errors but the app force closes everytime I hit a button. Here is my code:
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Button;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
public class BluetoothTest extends Activity
{
TextView labelConnect;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button openButton = (Button)findViewById(R.id.open);
Button closeButton = (Button)findViewById(R.id.close);
Button onButton = (Button)findViewById(R.id.onButton);
Button offButton = (Button)findViewById(R.id.offButton);
Button redButton = (Button)findViewById(R.id.redButton);
Button greenButton = (Button)findViewById(R.id.greenButton);
Button blueButton = (Button)findViewById(R.id.blueButton);
labelConnect = (TextView)findViewById(R.id.mylabel);
//Open Bluetooth
openButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
findBT();
openBT();
}
catch (IOException ex) { }
}
});
//Close Bluetooth
closeButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
closeBT();
}
catch (IOException ex) { }
}
});
//Red Button
redButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
redButton();
}
catch (IOException ex) { }
}
});
//Green Button
greenButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
greenButton();
}
catch (IOException ex) { }
}
});
//Blue Button
blueButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
blueButton();
}
catch (IOException ex) { }
}
});
//On Button - set strip to white
onButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
onButton();
} catch (Exception e) {
// TODO: handle exception
}
}
});
//Off Button - set strip to all OFF
offButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
offButton();
} catch (Exception e) {
// TODO: handle exception
}
}
});
} // end onCreate
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
labelConnect.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
if(device.getName().equals("BTNode0")) // Change to match RN42 - node name
{
mmDevice = device;
Log.i("ArduinoBT", "findBT found device named " + mmDevice.getName());
Log.i("ArduinoBT", "device address is " + mmDevice.getAddress());
break;
}
}
}
labelConnect.setText("Bluetooth Device Found");
}
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
labelConnect.setText("BT << " + mmDevice.getName() + " >> is now open ");
}
void closeBT() throws IOException
{
mmOutputStream.close();
mmSocket.close();
labelConnect.setText("Bluetooth Closed");
}
void offButton() throws IOException
{
mmOutputStream.write("0".getBytes());
}
void redButton() throws IOException
{
mmOutputStream.write("1".getBytes());
}
void greenButton() throws IOException
{
mmOutputStream.write("2".getBytes());
}
void blueButton() throws IOException
{
mmOutputStream.write("3".getBytes());
}
void onButton() throws IOException
{
mmOutputStream.write("4".getBytes());
}
}
And here is my log for what happens when I hit the connect button
04-25 12:15:10.771: W/asset(22604): Copying FileAsset 0x74c0a9d8 (zip:/data/app/Android.Arduino.Bluetooth-2.apk:/resources.arsc) to buffer size 1912 to make it aligned.
04-25 12:15:10.821: D/RenderPolicy(22604): ViewRootImpl.enableHardwareAcceleration -> enableRenderPolicy
04-25 12:15:10.881: I/Adreno-EGL(22604): <qeglDrvAPI_eglInitialize:316>: EGL 1.4 QUALCOMM build: (CL4169980)
04-25 12:15:10.881: I/Adreno-EGL(22604): OpenGL ES Shader Compiler Version: 17.01.10.SPL
04-25 12:15:10.881: I/Adreno-EGL(22604): Build Date: 02/04/14 Tue
04-25 12:15:10.881: I/Adreno-EGL(22604): Local Branch:
04-25 12:15:10.881: I/Adreno-EGL(22604): Remote Branch:
04-25 12:15:10.881: I/Adreno-EGL(22604): Local Patches:
04-25 12:15:10.881: I/Adreno-EGL(22604): Reconstruct Branch:
04-25 12:15:12.363: W/dalvikvm(22604): threadid=1: thread exiting with uncaught exception (group=0x41625e18)
04-25 12:15:12.373: E/AndroidRuntime(22604): FATAL EXCEPTION: main
04-25 12:15:12.373: E/AndroidRuntime(22604): Process: Android.Arduino.Bluetooth, PID: 22604
04-25 12:15:12.373: E/AndroidRuntime(22604): java.lang.NullPointerException
04-25 12:15:12.373: E/AndroidRuntime(22604): at Android.Arduino.Bluetooth.BluetoothTest.openBT(BluetoothTest.java:185)
04-25 12:15:12.373: E/AndroidRuntime(22604): at Android.Arduino.Bluetooth.BluetoothTest$1.onClick(BluetoothTest.java:53)
04-25 12:15:12.373: E/AndroidRuntime(22604): at android.view.View.performClick(View.java:4480)
04-25 12:15:12.373: E/AndroidRuntime(22604): at android.view.View$PerformClick.run(View.java:18673)
04-25 12:15:12.373: E/AndroidRuntime(22604): at android.os.Handler.handleCallback(Handler.java:733)
04-25 12:15:12.373: E/AndroidRuntime(22604): at android.os.Handler.dispatchMessage(Handler.java:95)
04-25 12:15:12.373: E/AndroidRuntime(22604): at android.os.Looper.loop(Looper.java:157)
04-25 12:15:12.373: E/AndroidRuntime(22604): at android.app.ActivityThread.main(ActivityThread.java:5872)
04-25 12:15:12.373: E/AndroidRuntime(22604): at java.lang.reflect.Method.invokeNative(Native Method)
04-25 12:15:12.373: E/AndroidRuntime(22604): at java.lang.reflect.Method.invoke(Method.java:515)
04-25 12:15:12.373: E/AndroidRuntime(22604): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1069)
04-25 12:15:12.373: E/AndroidRuntime(22604): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:885)
04-25 12:15:12.373: E/AndroidRuntime(22604): at dalvik.system.NativeStart.main(Native Method)
As they have already said in the comments, the mmDevice you are trying to use in the openBT method is null, because no device was found in the findBT method and the variable was not initialized. You need to fix your code so that you don't try to open the connection if the device was not found.
The other main issue in your code, once you solve this, is the SocketConnection you are trying to open in the Main Thread. Button handlers and GUI events are executed in the main thread, so your openBT should be moved to a separate thread (or better, a Service).
I am developing my first android app. I have been created a Service class which role is to check if any new information on an external webpage. The HTTP request and service work as i should, but after a while I get these OutOfMemoryError.
Are someone able to see where the Service gather all that memory?
Error message 1.
java.lang.OutOfMemoryError: pthread_create (stack size 16384 bytes) failed: Try again
at java.lang.VMThread.create(Native Method)
at java.lang.Thread.start(Thread.java:1029)
at org.apache.http.impl.conn.tsccm.AbstractConnPool.enableConnectionGC(AbstractConnPool.java:140)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.createConnectionPool(ThreadSafeClientConnManager.java:120)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.(ThreadSafeClientConnManager.java:98)
at com.loopj.android.http.AsyncHttpClient.(AsyncHttpClient.java:210)
at com.loopj.android.http.AsyncHttpClient.(AsyncHttpClient.java:149)
at com.loopj.android.http.AsyncHttpClient.(AsyncHttpClient.java:119)
at com.quickit.app.MyService.checkUpdates(MyService.java:89)
at com.quickit.app.MyService.access$1(MyService.java:75)
at com.quickit.app.MyService$TimeDisplayTimerTask$1.run(MyService.java:68)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5105)
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:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)
Error message 2.
java.lang.OutOfMemoryError: thread creation failed
at java.lang.VMThread.create(Native Method)
at java.lang.Thread.start(Thread.java:1050)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:913)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:81)
at com.loopj.android.http.AsyncHttpClient.sendRequest(AsyncHttpClient.java:893)
at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:688)
at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:671)
at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:658)
at com.quickit.app.MyService.checkUpdates(MyService.java:90)
at com.quickit.app.MyService.access$1(MyService.java:75)
at com.quickit.app.MyService$TimeDisplayTimerTask$1.run(MyService.java:68)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5092)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
at dalvik.system.NativeStart.main(Native Method)
My service class.
public class MyService extends Service {
boolean login = false;
// constant
public static final long NOTIFY_INTERVAL = 10 * 1000; // 10 seconds
String address = Utilities.getAPIUrl();
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
SharedPreferences prefs = getSharedPreferences("com.quickit.app", Context.MODE_PRIVATE);
login = prefs.getBoolean("login", false);
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
public class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
if(login) {
checkUpdates();
}
}
});
}
}
private void checkUpdates() {
final SharedPreferences prefs = getSharedPreferences("com.quickit.app", Context.MODE_PRIVATE);
final String from_id = prefs.getInt("user", 0)+"";
final String lastCheck = prefs.getString("last_check", "0");
RequestParams params = new RequestParams();
params.put("type", "get_ask_questions");
params.put("fromid", from_id);
params.put("last_check", lastCheck);
AsyncHttpClient client = new AsyncHttpClient();
client.post(address, params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
try {
notification(response);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
Your code is constantly creating a new AsyncHttpClient object every time that timer expires! If the object never finishes its work, at some point, you will run out of memory.
Since you are just periodically checking for updates, you should make the AsyncHttpClient object static and just reuse it.
Look at http://loopj.com/android-async-http/ specifically, the Recommended Usage section.
I saw most of the related questions, but I couldn't find any that fixed my problem.
This is my code, and I have no idea what I'm doing wrong.
static class NamedFile {
public File f;
public String name;
public String ext;
public String path;
public BitmapDrawable icon;
public NamedFile (File file) {
f = file;
name = f.getName();
if (f.isFile()) {
if (name.indexOf('.') != -1) {
ext = name.substring(name.lastIndexOf('.') + 1).trim().toLowerCase();
} else {
ext = "unknown";
}
}
path = f.getAbsolutePath();
if (ext == null) {
icon = mFolderIcon;
} else {
BitmapDrawable i = icons.get(ext);
if (i == null) {
try {
int rid = R.drawable.class.getField(ext).getInt(R.drawable.class);
icons.put(ext, new BitmapDrawable(Bitmap.createScaledBitmap(BitmapFactory.decodeResource(res, rid, mOpts), iconSize, iconSize, false)));
icon = icons.get(ext);
} catch (Exception e1) {}
} else {
icon = i;
}
}/* else if (ext.equals("jpeg") || ext.equals("jpg") || ext.equals("bmp") || ext.equals("gif") || ext.equals("png")) {
Bitmap b = BitmapFactory.decodeFile(path, mOpts);
if (b != null) {
icon = new BitmapDrawable(Bitmap.createScaledBitmap(b, iconSize, iconSize, false));
}
}*/
if (ext != null && (ext.equals("jpeg") || ext.equals("jpg") || ext.equals("bmp") || ext.equals("gif") || ext.equals("png"))) {
/*
Bitmap b = BitmapFactory.decodeFile(path, mOpts);
if (b != null) {
icon = new BitmapDrawable(Bitmap.createScaledBitmap(b, iconSize, iconSize, false));
}
*/
final Handler handler = new Handler() {
#Override
public void handleMessage(Message message) {
HashMap<String, Object> m = ((HashMap<String, Object>)message.obj);
sendThumbnail ((String)m.get("path"), (byte[])m.get("data"));
}
};
Thread thread = new Thread() {
public void writeInt (byte[] buff, int pos, int value) {
buff[pos] = (byte)(value >>> 24);
buff[pos + 1] = (byte)(value >>> 16);
buff[pos + 2] = (byte)(value >>> 8);
buff[pos + 3] = (byte)value;
}
#Override
public void run() {
try {
Bitmap b = BitmapFactory.decodeFile(path, mOpts);
if (b.getHeight() > 256 || b.getWidth() > 256) {
float r;
if (b.getHeight() > b.getWidth()) {
r = 128f / b.getHeight();
} else {
r = 128f / b.getWidth();
}
b = Bitmap.createScaledBitmap(b, (int)(r * b.getWidth()), (int)(r * b.getHeight()), false);
byte[] buffer = new byte[b.getWidth() * b.getHeight() * 4 + 8];
writeInt (buffer, 0, b.getWidth());
writeInt (buffer, 4, b.getHeight());
int i = 8;
for (int y = 0; y < b.getHeight(); y ++) {
for (int x = 0; x < b.getWidth(); x ++) {
writeInt (buffer, i, b.getPixel(x, y));
i += 4;
}
}
HashMap<String, Object> msg = new HashMap<String, Object>();
msg.put("path", path);
msg.put("data", buffer);
Message message = handler.obtainMessage(1, msg);
handler.sendMessage(message);
}
} catch (Exception e) {
sendLog (e.toString());
}
}
};
thread.start();
}
if (icon == null) {
icon = mFileIcon;
}
}
public NamedFile () {
}
public NamedFile simpleClone () {
final NamedFile nf = new NamedFile();
nf.name = name;
nf.ext = ext;
nf.path = path;
return nf;
}
}
This is nested inside an if statement that is in a static class' constructor function and the static class is in a public class that extends ListActivity. I'm new to Java.
Error:
05-01 20:21:58.810: E/AndroidRuntime(584): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
05-01 20:21:58.830: E/AndroidRuntime(584): java.lang.RuntimeException: An error occured while executing doInBackground()
05-01 20:21:58.830: E/AndroidRuntime(584): at android.os.AsyncTask$3.done(AsyncTask.java:200)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.lang.Thread.run(Thread.java:1096)
05-01 20:21:58.830: E/AndroidRuntime(584): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-01 20:21:58.830: E/AndroidRuntime(584): at android.os.Handler.<init>(Handler.java:121)
05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$NamedFile$1.<init>(FileTransferActivity.java:588)
05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$NamedFile.<init>(FileTransferActivity.java:588)
05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$GesturesLoadTask.doInBackground(FileTransferActivity.java:489)
05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$GesturesLoadTask.doInBackground(FileTransferActivity.java:1)
05-01 20:21:58.830: E/AndroidRuntime(584): at android.os.AsyncTask$2.call(AsyncTask.java:185)
05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-01 20:21:58.830: E/AndroidRuntime(584): ... 4 more
(FileTransferActivity.java:588 is final Handler handler = new Handler() {)
A Handler is basically a callback class that Android uses to asynchronously run code when you send it messages of some form. In order for a Handler to receive and handle messages in a separate thread from the UI thread, it must keep the thread open. That is where the Looper class comes in. Like in the example of the page, call Looper.prepare() at the top of the run() method, then call Looper.loop() at the bottom. The thread will stay open until you explicitly destroy it. In order to destroy a Looper thread, you must have a method in your Thread class that calls Looper.getMyLooper().quit().
An example thread class would be something like this:
class LooperThread extends Thread {
public Handler mHandler;
private volatile Looper mMyLooper;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
mMyLooper = Looper.getMyLooper();
Looper.loop();
}
public void killMe(){
mMyLooper.quit();
}
}
Run the thread normally by creating a new object of it.
LooperThread myLooperThread = new LooperThread();
Hold a reference to it. Then call:
myLooperThread.killMe();
Whenever you want the thread to die. This is usually in the onPause(), onStop(), or onDestroy() methods of the Activity.
Please note that a thread of this nature will stay open when the activity is closed so you must kill it before the user quits.
Runs the specified action on the UI thread
ActivityName.runOnUiThread(new Runnable() {
public void run()
{
//put your logic here
}
});
I recommend using HandlerThread as it prepares the looper for you.
http://developer.android.com/reference/android/os/HandlerThread.html