【问题标题】:Android App returning Null from APIAndroid App 从 API 返回 Null
【发布时间】:2017-02-11 15:53:31
【问题描述】:

构建一个 Android 应用程序以在 C# 中从 RESTful API 合并 Web 服务。我希望能够在此阶段仅检索一些原始 JSON 以确保连接正常工作。 API 的本地主机 URL 显示数据如下:

Android 应用程序中的 URL 字符串设置为外部 IP 地址,但当我在应用程序上调用数据时,应用程序只显示 null。

Android 应用代码 - 主活动:

public class MainActivity extends AppCompatActivity{

private static final String JSON_URL =
        "http://**.***.***.***:5495/api/StudentAPI/GetAllStudent";

private boolean networkOk;
TextView output;

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String message =
                intent.getStringExtra(myService.MY_SERVICE_PAYLOAD);
        output.append(message + "\n");
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    output = (TextView) findViewById(R.id.output);

    LocalBroadcastManager.getInstance(getApplicationContext())
            .registerReceiver(mBroadcastReceiver,
                    new IntentFilter(myService.MY_SERVICE_MESSAGE));

    networkOk = NetworkHelper.hasNetworkAccess(this);
    output.append("Network ok: " + networkOk);
}

@Override
protected void onDestroy() {
    super.onDestroy();

    LocalBroadcastManager.getInstance(getApplicationContext())
            .unregisterReceiver(mBroadcastReceiver);
}

public void  runClickHandler(View view){
    Intent intent = new Intent(this, myService.class);
    intent.setData(Uri.parse(JSON_URL));
    startService(intent);
}

public void clearClickHandler(View view){output.setText(""); }


}

我的服务:

public class myService extends IntentService {

public static final String TAG = "MyService";
public static final String MY_SERVICE_MESSAGE = "myServiceMessage";
public static final String MY_SERVICE_PAYLOAD = "myServicePayload";

public myService() {
    super("MyService");
}

@Override
protected void onHandleIntent(Intent intent) {
    Uri uri = intent.getData();
    Log.i(TAG, "onHandleIntent: " + uri.toString());

    String response;

    try {
        response =
                HttpHelper.downloadUrl(uri.toString());
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }

    Intent messageIntent = new Intent(MY_SERVICE_MESSAGE);
    messageIntent.putExtra(MY_SERVICE_PAYLOAD, response);
    LocalBroadcastManager manager =
            LocalBroadcastManager.getInstance(getApplicationContext());
    manager.sendBroadcast(messageIntent);

}

@Override
public void onCreate() {
    super.onCreate();
    Log.i(TAG, "onCreate");
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.i(TAG, "onDestroy");
}
}

网络助手:

public class NetworkHelper {

public static boolean hasNetworkAccess(Context context){

    ConnectivityManager cm = (ConnectivityManager)
            context.getSystemService(Context.CONNECTIVITY_SERVICE);
    try {
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null &&
                activeNetwork.isConnectedOrConnecting();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}
}

Http Helper 类:

public class HttpHelper {

/**
 * Returns text from a URL on a web server
 *
 * @param address
 * @return
 * @throws IOException
 */
public static String downloadUrl(String address) throws IOException {

    InputStream is = null;
    try {

        URL url = new URL(address);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.connect();

        int responseCode = conn.getResponseCode();
        if (responseCode != 200) {
            throw new IOException("Got response code " + responseCode);
        }
        is = conn.getInputStream();
        return readStream(is);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (is != null) {
            is.close();
        }
    }
    return null;
}

/**
 * Reads an InputStream and converts it to a String.
 *
 * @param stream
 * @return
 * @throws IOException
 */
private static String readStream(InputStream stream) throws IOException {

    byte[] buffer = new byte[1024];
    ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
    BufferedOutputStream out = null;
    try {
        int length = 0;
        out = new BufferedOutputStream(byteArray);
        while ((length = stream.read(buffer)) > 0) {
            out.write(buffer, 0, length);
        }
        out.flush();
        return byteArray.toString();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    } finally {
        if (out != null) {
            out.close();
        }
    }
}

}

【问题讨论】:

  • 它是否在本地主机上工作?
  • 没有。当我在物理设备上进行测试时,我认为您需要外部 IP 地址。
  • 设置断点并找出问题所在。你有200吗?还有什么?抛出异常?你需要先做背景调查,没有人会为你构建这么多代码来调试它。
  • 什么是 responseCode,它显示在 downloadUrl() 中?
  • 接受@GabeSechen 的建议我已经在调试模式下运行,它表明连接似乎存在一个错误。 java.net.ConnectException:在 15000 毫秒后无法连接到 /**.***.***.***(端口 5495):isConnected 失败:ECONNREFUSED(连接被拒绝)这可能是 API 端口的问题吗正在使用吗?

标签: c# android json rest


【解决方案1】:

首先,确定问题出在服务中还是在您的应用中。

使用所有给定的参数从here 发出 HTTP 请求,如果有效,则您的服务正常。

现在,请按照以下步骤找出本地方面的问题。

downloadUrl() 上运行调试并检查responseCode 的值,如果它是200,那么请求是好的,现在只需清理并重建您的项目。

如果不是 200,请按照以下步骤操作:

  1. extends 来自 AsyncTask 的 HttpHelper 类
  2. 现在将您的代码从downloadUrl() 移至doInBackground()
  3. 现在为 responseCode 调试此类。

【讨论】:

  • 我已采取上述步骤并发现以下内容: 服务很好并返回原始 json 我已确保端口接受防火墙设置内的连接 我按照您所说的重新格式化了代码使用公共 IP 地址 (31.185.xx) 时,连接被拒绝。使用私有地址 (192.168.x.x) 时,它会以 400 responseCode 响应。
  • 为此使用私有 IP 地址,但在此之前,允许来自您的服务器/dbms 等的外部请求。如果是 MySQL,我必须在 apache 上允许它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
相关资源
最近更新 更多