【问题标题】:Java Android: Calling a MethodJava Android:调用方法
【发布时间】:2013-05-14 09:14:50
【问题描述】:

我正在构建一个列表视图 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;
    }

}

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

【问题讨论】:

  • 嗯有什么问题?
  • 当我单击列表项之一时,我收到“应用程序已停止工作”消息。
  • 请从 logcat 发布堆栈跟踪。它将准确显示问题所在和位置。
  • 我已经打开了 LogCat 窗口,你需要知道什么?

标签: java android networking methods call


【解决方案1】:

您应该使用AsyncTask 或Thread 和Handler。

这是Thread 和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();
    }
}

【讨论】:

  • 这一切看起来正是我想要的我已经检查了好几次,但是当单击列表项时我仍然收到“应用程序已停止工作”消息:/有什么想法吗?
  • 发布堆栈跟踪,或最后 5 行到异常
【解决方案2】:

查看您的堆栈跟踪,我想您可能会收到NetworkOnMaintThreadException,因为您正在主/UI 线程上进行 HTTP 连接。在单独的线程中执行此操作,也许使用AsyncTask,那么你应该没问题。

【讨论】:

【解决方案3】:

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

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

【讨论】:

  • 我使用的是 4.2.2,所以我必须创建一个新的 AsyncTask 类来 ping url?
  • 是的,你需要。通常你应该在你的堆栈跟踪中看到他的帖子中提到的 soren.qvist 的异常。
猜你喜欢
  • 2018-11-07
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 2011-07-09
  • 1970-01-01
相关资源
最近更新 更多