0

我正在构建一个列表视图 android 应用程序。我希望在从数组中的列表中单击一个 url 时返回一条消息,告诉用户该站点是离线还是在线。我通过快速 ping 来执行此操作,它返回一个布尔值来说明这一点。我是一个 java 新手,我知道这与我调用 pinUrl() 方法的方式有关,因为当我从 onListItemClick() 中删除所说的 if 语句时,应用程序不会崩溃。

这是我的 MainActivity 供参考:

package com.seven.webtools;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

@SuppressLint("UseValueOf")
public class MainActivity extends ListActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Resources res = getResources();
    String[] Sites = res.getStringArray(R.array.Sites);
    setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Sites));

}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    // Get the selected url
    super.onListItemClick(l, v, position, id);
    Object o = this.getListAdapter().getItem(position);
    String address = o.toString();

    //Ping the address
    String Status = "offline";
    if (MainActivity.pingUrl(address) == true){
        Status = "online";
    }

    //Return the result
    Toast.makeText(this, address + " is " + Status, Toast.LENGTH_LONG).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public static boolean pingUrl(final String address) {
     try {
      final URL url = new URL("http://" + address);
      final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
      urlConn.setConnectTimeout(1000 * 10); // mTimeout is in seconds
      final long startTime = System.currentTimeMillis();
      urlConn.connect();
      final long endTime = System.currentTimeMillis();
      if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
       System.out.println("Time (ms) : " + (endTime - startTime));
       System.out.println("Ping to "+address +" was success");
       return true;
      }
     } catch (final MalformedURLException e1) {
      e1.printStackTrace();
     } catch (final IOException e) {
      e.printStackTrace();
     }
     return false;
    }

}

如果你能帮助我,非常感谢:)

4

3 回答 3

1

您应该使用 anAsyncTask或 a Threadand Handler

Thread这是 a和的示例Handler

public class MainActivity extends ListActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Resources res = getResources();
        String[] Sites = res.getStringArray(R.array.Sites);
        setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Sites));
    }

    // Here is where we create our Handler that will receive the Message from the thread.
    private Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            StringBuilder str = new StringBuilder();
            str.append((String) msg.obj).append("\r\n");
            str.append("response:  " + msg.arg1).append("\r\n");
            str.append("time: " + msg.arg2).append("\r\n");

            System.out.println(str.toString());
        }
    };

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id)
    {
        super.onListItemClick(l, v, position, id);

        final String address = l.getItemAtPosition(position).toString();

        // We create a new thread and implements the Runnable interface
        new Thread(new Runnable()
        {
            public void run()
            {
                URL url;
                HttpURLConnection connection = null;

                try
                {
                    url = new URL(address);

                    connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(10 * 1000);
                    connection.setReadTimeout(10 * 1000);

                    long start = System.currentTimeMillis();

                    connection.connect();

                    int response = connection.getResponseCode();

                    long end = System.currentTimeMillis();

                    // Here we create a new Message to send to the Handler object on the Activity
                    //  Send the response code, ping time, and the address
                    Message msg = Message.obtain(handler);
                    msg.arg1 = response;
                    msg.arg2 = (int) (end - start);
                    msg.obj = address;
                    msg.sendToTarget();
                }
                catch(MalformedURLException e)
                {
                    e.printStackTrace();
                }
                catch(IOException e)
                {
                    e.printStackTrace();
                }
                finally
                {
                    connection.disconnect();
                }
            }
        }).start();
    }
}
于 2013-05-19T21:06:42.390 回答
0

您使用的是哪个 Android 版本?App 可能会因为你在 UI-Main-Thread 上进行网络调用而崩溃,这意味着 UI 在网络调用期间冻结。在旧版本中,它可以正常工作而不会出现异常。从版本 2.3.x(如果我错了,请纠正我)你得到了android.os.NetworkOnMainThreadException.

查看这篇文章以了解如何解决此问题的更多信息: -如何修复 android.os.NetworkOnMainThreadException?

于 2013-05-19T20:17:55.993 回答
0

看看你的堆栈跟踪,我想你可能会得到一个NetworkOnMaintThreadException,因为你在 Main/UI 线程上进行 HTTP 连接。在一个单独的线程中执行它,也许通过使用一个AsyncTask,那么你应该没问题。

于 2013-05-19T20:15:44.003 回答