7

次のコードを使用して、Android デバイスを ftp サーバー (Android 内部ストレージ) にしています。の例外が発生していますos.android.NetworkOnMainThread。onStart コードを に入れようとしましたAsyncTaskが、アプリが実行されず、起動時にクラッシュします。Android の ftp サーバーに関するヘルプは、どのように動作させるか分からないため、非常に役に立ちます。

MainActivityコードはこちら

package com.googlecode.simpleftp;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;


public class FTPServer extends Activity {
    private static int COMMAND_PORT = 2121;
    static final int DIALOG_ALERT_ID = 0;
    private static ExecutorService executor  = Executors.newCachedThreadPool();

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.my_menu, menu);
            return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {    
            // Handle item selection    
            switch (item.getItemId()) {
                    case R.id.new_game:    
                            System.out.println("New game button is pressed!");
                            //newGame();        
                            return true;    
                    case R.id.quit:        
                            System.out.println("Quit button is pressed!");
                            showDialog(DIALOG_ALERT_ID);        
                            return true;    
                    default:        
                            return super.onOptionsItemSelected(item);    }
    }

    @Override
    protected Dialog onCreateDialog(int id){
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("Are you sure you want to exit?")
            .setCancelable(false).setPositiveButton("yes", new DialogInterface.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int id){
                            FTPServer.this.finish();
                    }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();

                    }
            });
            AlertDialog alert = builder.create();
            return alert;
    }

ここにServerPIコードがあります

 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.Socket;

 public class ServerPI implements Runnable{
    private Socket clientSocket;
    private BufferedReader in;
    private PrintWriter out;

    private String baseDir;
    private String relativeDir;
    private String absoluteDir;
    private String fileName;
    private String filePath;

    public ServerPI(Socket incoming) throws IOException{
            this.clientSocket = incoming;
            in = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
            out = new PrintWriter(this.clientSocket.getOutputStream(), true);

            baseDir = new File("").getAbsolutePath();

            relativeDir = "/";
            absoluteDir = baseDir + relativeDir;
            fileName = "";
            filePath = absoluteDir + "/" + fileName;
    }

    private void readCommandLoop() throws IOException {
            String line = null;
            reply(220, "Welcome to the SimpleFTP server!");
            while((line = in.readLine()) != null){
                    int replyCode = executeCommand(line.trim());
                    if(replyCode == 221){
                            return;
                    }
            }
    }

    private int executeCommand(String trim) {
            // TODO Auto-generated method stub
            return 0;
    }

    public int reply(int statusCode, String statusMessage){
            out.println(statusCode + " " + statusMessage);
            return statusCode;
    }

    @Override
    public void run(){
            try{
                    this.readCommandLoop();
            } catch (IOException e){
                    e.printStackTrace();
            }
            finally {
                    try {
                            if(in != null){
                                    in.close();
                                    in = null;
                            }
                            if(out != null){
                                    out.close();
                                    out = null;
                            }
                            if (clientSocket != null){
                                    clientSocket.close();
                                    clientSocket = null;
                            }
                    }
                    catch (IOException e){
                            e.printStackTrace();
                    }
            }
    }
    }

コードをAsyncTaskに入れました。ここにあります

   private class LongOperation extends AsyncTask<String, Void, String> {

      @Override
      protected String doInBackground(String... params) {
           ServerSocket s = null;
    Socket incoming = null;

    try{
            s = new ServerSocket(COMMAND_PORT);
            String ip = (s.getInetAddress()).getHostAddress();
            Context context = this.getApplicationContext();
            CharSequence text = ip;
            int duration = Toast.LENGTH_LONG;

            Toast toast = Toast.makeText(context, text, duration);
            Thread.sleep(1000);
            toast.show();
            while(true){
                    incoming = s.accept();
                    executor.execute(new ServerPI(incoming));
            }
    }
    catch(Exception e){
            System.out.println(e.toString());
            e.printStackTrace();
    }
    finally{
            try
                    {
                            if(incoming != null)incoming.close();
                    }
                    catch(IOException ignore)
                    {
                            //ignore
                    }

                    try
                    {
                            if (s!= null)
                            {
                                    s.close();
                            }
                    }
                    catch(IOException ignore)
                    {
                            //ignore
                    }
    }

            return "Executed";
      }      

      @Override
      protected void onPostExecute(String result) {               
      }

      @Override
      protected void onPreExecute() {
      }

      @Override
      protected void onProgressUpdate(Void... values) {
      }
}

onCreate メソッドで longOpertation を呼び出しています。起動時にアプリがクラッシュする問題は何ですか。

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_fullscreen);
            new LongOperation().execute();
    }
4

5 に答える 5

2

そこで、アプリケーションのサービスとして Swiftp アプリケーション (オープンソース) を使用して、タスクを達成するのに役立ちました。助けてくれたすべての人に感謝します。誰かがフォローしたい場合は、ここにリンクがあります

于 2013-05-02T07:56:42.890 に答える
2

while(true){ incoming = s.accept(); ...}それを OnStart() に入れることはできません。それはスレッドで行う必要があります。あなたServerSocket s = null;の活動の変数であるべきです。

于 2013-04-09T08:13:05.910 に答える
1

ここにコードを投稿してください。

NetworkOnMainthreadException は、メイン UI スレッドでネットワーク関連の操作を実行している可能性があるために発生します。この目的には asynctask を使用する必要があります

これは、Honeycom SDK 以降を対象とするアプリケーションに対してのみスローされます。以前のバージョンの SDK を対象とするアプリケーションは、メイン イベント ループ スレッドでネットワークを実行できますが、推奨されません。

http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

class TheTask extends AsyncTask<Void,Void,Void>
{
protected void onPreExecute()
  {           super.onPreExecute();
             //display progressdialog.
  }  

protected void doInBackground(Void ...params)//return result here
{  
//http request. do not update ui here
//call webservice
//return result here
return null;
 } 

protected void onPostExecute(Void result)//result of doInBackground is passed a parameter
{     
    super.onPostExecute(result);
    //dismiss progressdialog.
    //update ui using the result returned form doInbackground()
} 
}

http://developer.android.com/reference/android/os/AsyncTask.htmlThe 4 Stepsという見出しの下のトピックを確認してください。

asynctask の動作例 @ Android 4.0.3 でチュートリアルを使用するには、AsynxTasc を使用する必要がありましたが、まだ動作しませんか? .

上記は doInBakckground() で webserive 呼び出しを行います。結果を返し、onPostExecute() の textview に結果を設定して ui を更新します。

于 2013-04-09T07:15:29.377 に答える
0

Android 3.0以上ではメインスレッドでネットワーク操作ができません。このネットワーク操作にはAsyncTaskを使用します。詳細については、これを参照してください

于 2013-04-09T07:22:06.303 に答える