我得到了这个例外。什么时候,我正在尝试运行我的程序。在我的程序中,我正在执行AsyncTask
对于每个下载和上传任务,我创建了新的AsyncTask
对象,并尝试在后台运行它。我试图找到我的错误。但我无法找到我错的地方。下面是我的堆栈跟踪和我的程序代码 -
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
这是我的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();
}
}
}
这是我的选项菜单。我用它做了我的asyn任务 我在我的主要活动中使用的变量有助于完成这项任务:
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);
}
}
嗨,当我试图显示吐司时,如下面的评论中所述,我得到了相同的异常。请查看下面的代码,我曾经在我的异步任务中显示Toast:
(new Activity()).runOnUiThread(new Runnable(){@Override public void run() {//Your Toast
Toast.makeText(context, "AccessPC Download Task failed ",Toast.LENGTH_LONG).show();
}});
我是否需要对异步任务代码或选项菜单代码进行任何更改?
我使用了这样的处理程序:
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();
}
};
我正在调用这样的处理程序:
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);
但是如何调用非静态方法?我是否需要为主类创建一个对象(类t扩展列表活动)?
嗨,请查看我从上面的异步任务和菜单发布的选项菜单中选择“退出”操作时获得的另一个例外。如何避免这种异常:
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)
答案 0 :(得分:3)
Can't create handler inside thread that has not called Looper.prepare()
,错误信息相当简单。
您在Handler
(后台线程)中创建了一个AsyncTask.doInBackground()
对象,该对象需要该线程中的消息泵,即Looper.prepare()
。
我认为将您的Handler
对象的创建从AysncTask中移出到UI线程可能更容易。
以下是OP编辑他/她的问题后的编辑
Toast.makeText(context, "AccessPC Upload task "+tasknumber+" Started", Toast.LENGTH_LONG).show();
上面的行根本不允许在后台线程中显示Toast
消息更新 UI ,这必须发生在UI线程中。
再次编辑
您可以使用在UI线程中创建的Handler
来发送消息,并在处理程序中通过显示所需的Toast消息来处理该消息。
再次编辑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);
...
答案 1 :(得分:1)
如下所示写Toast消息我希望它能正常工作。
getApplicationContext().runOnUiThread(new Runnable() {
@Override
public void run() {
//Your Toast
}
});
答案 2 :(得分:0)
评论您使用非UI线程显示的所有Toast消息。我认为这个问题..