2013-05-19 47 views
0

我正在构建一个列表视图android应用程序。 我想要一个消息被返回时,从列表中点击一个网址,告诉用户该网站是否离线或联机。我通过一个快速的ping来完成这个工作,它返回一个布尔值来说明这一点。我是一个java新手,我知道这是我调用pinUrl()方法的方式,因为当我从onListItemClick()移除所述if语句时,该应用程序不会崩溃。Java Android:调用方法

这里是我的参考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; 
    } 

} 

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

+0

嗯什么问题呢? –

+0

当我点击其中一个列表项目时,我收到“应用程序已停止工作”消息。 –

+0

请从logcat发布堆栈跟踪。它将显示问题的具体内容和位置。 – Simon

回答

0

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

+0

所以我必须做一个新的AsyncTask类来ping网址? –

+0

@gravysam是的,你可以检查这个以前的答案,我做了同一主题:http://stackoverflow.com/questions/16572285/gson-and-google/16572315#16572315 –

0

您正在使用哪个Android版本?该应用程序可能会因为您正在UI-Main-Thread上进行网络调用而崩溃,这意味着在网络调用期间UI会冻结。在旧版本中,它的工作原理没有发生异常。自从版本2.3.x(纠正我,如果我错了),你会得到android.os.NetworkOnMainThreadException

以在这个岗位看看更多的信息,如何解决这个问题: - How to fix android.os.NetworkOnMainThreadException?

+0

我使用4.2.2,所以我必须创建一个新的AsyncTask类来ping网址? –

+0

是的,你需要。通常你应该在你的stacktrace中看到soren.qvist在他的帖子中提到的异常。 – Woda

1

您应该使用一个AsyncTaskThreadHandler

这里的ThreadHandler一个例子:

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(); 
    } 
} 
+0

这一切看起来正是我想要的东西,我已经通过它检查了好几次,但当点击列表项时仍然出现“应用程序已停止工作”消息:/任何想法? –

+0

发布堆栈跟踪,或最后5行直至异常 – mrres1