0

この例外が発生しています。いつ、私は自分のプログラムを実行しようとしています。私のプログラムでは、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ヘルパーです

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);
        }
    }

こんにちは、以下のコメントの1つに記載されているように、トーストを表示しようとすると、同じ例外が発生しました。非同期タスクでトーストを表示するために使用した以下のコードを参照してください。

(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はリストアクティビティを拡張します)のオブジェクトを作成する必要がありますか?

こんにちは、上記の非同期タスクのオプションメニューから「QUIT」操作を選択したときにiveが取得した別の例外と、投稿されたメニューを参照してください。この例外を回避する方法:

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)
4

3 に答える 3

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();

上記の行は、バックグラウンド スレッドでは許可されていません。メッセージが UI スレッドで発生する必要があるUIToastを更新していることを示しています。

もう一度編集

UI スレッドで作成された を使用しHandlerてメッセージを送信し、ハンドラーで目的のトースト メッセージを表示してそのメッセージを処理できます。

もう一度編集 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);
...

Handler の詳細については、最初にjavadocを参照してください。Googleはさらに多くの情報を提供します。

于 2012-05-07T04:50:43.273 に答える
1

以下のようにトーストメッセージを書いてください。うまくいくことを願っています。

getApplicationContext().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                       //Your Toast 

                    }
                });
于 2012-05-07T05:23:55.270 に答える
0

非 UI スレッドを使用して表示しているすべてのトースト メッセージにコメントを付けます。これが問題だと思います..

于 2012-05-07T05:23:34.790 に答える