0

この例外が発生しましたが、その理由がわかりません。それが私が持っているクラスです。dbに接続するScheduledExecutorServiceであるクラスを開始するサービスを開始するアクティビティ(これが接続の理由です)。

サービスを介して接続しようとしたときに、この例外が発生した理由を理解しましたが、それを行うために新しいクラス/タスクを作成しましたが、まだこの例外が発生しています。

たくさんのコードがあり、問題はコード自体ではなく、このシステムの管理方法にある可能性があるため、コードを添付しませんでした。


この場合に a が適切でない理由の詳細については、サービスを介した mysql への接続の管理を参照してください。Thread

EDIT コードの添付ファイル: これは、詳細をデータベースに送信する 3 番目のクラスです。

public class SendLocation 
{
    private String lastAddress;
    private int id;
    private Connection conn;
    private PreparedStatement stmt;
    private LocationService ls1;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    public SendLocation(int id,LocationService ls1)
    {
        this.lastAddress = "";
        this.id = id;
        this.conn = null;
        this.sqlConnect();
        this.sqlInsertStatement();
        this.ls1 = ls1;
    }
    public void send()
    {
        final Runnable sender = new Runnable() 
        {
            public void run() 
            { 
                if(!lastAddress.equals(ls1.getAddress()) && !ls1.getAddress().equals(""))
                {
                    lastAddress = ls1.getAddress();
                    try 
                    {
                        stmt.setInt(1, id);
                        stmt.setString(2, lastAddress);
                        stmt.execute();
                    } 
                    catch (SQLException e) {
                        e.printStackTrace();
                    } 
                }
            }
        };


        final ScheduledFuture sendHandle = 
                scheduler.scheduleAtFixedRate(sender, 1, 1, TimeUnit.SECONDS);

        scheduler.schedule(new Runnable()
        {
            public void run() 
            { 
                sendHandle.cancel(true); 
            }
        }, 60 * 60, TimeUnit.SECONDS);
    }



     public boolean sqlConnect()
        {
            try {
                Class.forName(Config.DRIVER).newInstance();
                DriverManager.setLoginTimeout(100);
                this.conn = DriverManager.getConnection(Config.URL+Config.DBNAME,
                        Config.USERNAME,Config.PASSWORD);
                return true;

            }catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
     public void sqlInsertStatement()
     {
         try {
             this.stmt = conn.prepareStatement
                     ("INSERT INTO locations(id, location) VALUES (?,?)");
         }catch (SQLException e1) {
             e1.printStackTrace();
         }
     }
}

編集

タスクをスレッドに変更しました。新しいコードは次のとおりです。

public class SendLocation extends Thread
{
    private String lastAddress;
    private int id;
    private Connection conn;
    private PreparedStatement stmt;
    private LocationService ls1;
    private boolean run;

    public SendLocation(int id,LocationService ls1)
    {
        this.lastAddress = "";
        this.id = id;
        this.conn = null;
        this.sqlConnect();
        this.sqlInsertStatement();
        this.ls1 = ls1;
        this.run = true;
    }
    public void run() 
    { 
        while(run)
        {
            if(!lastAddress.equals(ls1.getAddress()) && !ls1.getAddress().equals(""))
            {
                lastAddress = ls1.getAddress();
                try 
                {
                    stmt.setInt(1, id);
                    stmt.setString(2, lastAddress);
                    stmt.execute();
                    sleep(1000);
                } 
                catch (Exception e) {
                    e.printStackTrace();
                } 
            }
        }
    }       
    public void destroy()
    {
        this.run = false;
    }
    public boolean sqlConnect()
    {
        try {
            Class.forName(Config.DRIVER).newInstance();
            DriverManager.setLoginTimeout(100);
            this.conn = DriverManager.getConnection(Config.URL+Config.DBNAME,
                    Config.USERNAME,Config.PASSWORD);
            return true;

        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
     public void sqlInsertStatement()
     {
         try {
             this.stmt = conn.prepareStatement
                     ("INSERT INTO locations(id, location) VALUES (?,?)");
         }catch (SQLException e1) {
             e1.printStackTrace();
         }
     }
}

NetworkOnMainThread 例外が発生したのはなぜですか??

4

2 に答える 2

3

例外は、ネットワーク操作など、UI スレッドで長期的な操作を実行していることを意味します。Android 3以降、これらの操作は許可されておらず、例外がスローされます。したがって、例外を回避するには、コードを非同期で実行する必要があります。クラスを作成する必要はありませんが、Threadorを拡張するクラスを作成する必要がありますAsyncTask

于 2013-01-09T13:28:40.690 に答える
2

問題を解決するには、以下のガイドを参照してください。

 android.os.NetworkOnMainThreadException

このエラーはHoneyComb (3.0 以降) で発生します。

ドキュメントにあるように、メインスレッドでネットワーク操作を実行することはできません。これに乗るには、ハンドラーまたは asynctask を使用する必要があります。AFAIKそれを行う別の方法はありません。

詳細については、これを参照してください。ICS がアプリをクラッシュさせる理由

以下のコード スニペットを使用してみてください

new Thread(){
    public void run(){
        //do your Code Here    
    }
}.start();
于 2013-01-09T13:30:57.253 に答える