我正在尝试调用应返回Json的Https服务。但是,我无法正确设置连接。我使用了本主题“正确”答案中的代码:How to call https web service in Android
这是我的代码exaclty:
MainActivity.java
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import java.io.BufferedReader;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context con = getApplicationContext();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
TextView t = (TextView) findViewById(R.id.textView1);
HttpGet httpGet = new HttpGet("https://...");
HttpClient httpClient = new NetworkUtility().getDefaultHttpClient(con, "https://...);
try {
HttpResponse response = httpClient.execute(httpGet); //line 44
if(response!=null) t.setText("1");
} catch (IOException e) {
t.setText("IO Exception");
}
}
public void apiCall(View v) {
EditText ed = (EditText) findViewById(R.id.editText1);
TextView t = (TextView) findViewById(R.id.textView1);
String username = ed.getText().toString();
BufferedReader reader = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
NetworkUtility.java
import java.io.IOException;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import android.content.Context;
import android.util.Log;
public class NetworkUtility {
protected static final String TAG = NetworkUtility.class.getSimpleName();
private static final int HTTP_CONNECTION_TIMEOUT = 150000;
public static HttpClient getDefaultHttpClient(Context context,
String targetUrl) {
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params,
HTTP_CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_CONNECTION_TIMEOUT);
try {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", new MySSLSocketFactory(
context.getApplicationContext(), targetUrl), 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
e.printStackTrace();
return new DefaultHttpClient(params);
}
}
private static class MyTrustManager implements X509TrustManager {
private X509TrustManager mOriginalX509TrustManager;
private Context mContext;
private String mTargetUrl;
public MyTrustManager(Context context, String targetUrl) {
try {
this.mContext = context;
this.mTargetUrl = targetUrl;
TrustManagerFactory originalTrustManagerFactory = TrustManagerFactory
.getInstance("X509");
originalTrustManagerFactory.init((KeyStore) null);
TrustManager[] originalTrustManagers = originalTrustManagerFactory
.getTrustManagers();
this.mOriginalX509TrustManager = (X509TrustManager) originalTrustManagers[0];
} catch (Exception e) {
e.printStackTrace();
}
}
public void checkClientTrusted(X509Certificate[] cert, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] cert, String authType)
throws CertificateException {
try {
mOriginalX509TrustManager.checkServerTrusted(cert, authType);
} catch (CertificateException originalException) {
X509Certificate certificate = getCertificateToInstall(cert);
Log.d(TAG, "Showing dialog for certificate exception...");
throw originalException;
}
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
private static X509Certificate getCertificateToInstall(
X509Certificate[] certificates) {
X509Certificate result = null;
try {
KeyStore ks = KeyStore.getInstance("AndroidCAStore");
if (ks != null) {
ks.load(null, null);
boolean certFound = false;
for (X509Certificate certificate : certificates) {
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = (String) aliases.nextElement();
X509Certificate cert = (X509Certificate) ks
.getCertificate(alias);
if (certificate.equals(cert) == true) {
certFound = true;
break;
}
}
if (certFound == false) {
Log.d(TAG, "Not found certificate");
result = certificate;
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static class MySSLSocketFactory extends SSLSocketFactory {
private javax.net.ssl.SSLSocketFactory mFactory;
public MySSLSocketFactory(Context context, String targetUrl)
throws KeyManagementException, NoSuchAlgorithmException,
KeyStoreException, UnrecoverableKeyException {
super((KeyStore) null);
try {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { new MyTrustManager(
context, targetUrl) }, null);
mFactory = sslcontext.getSocketFactory();
setHostnameVerifier(new AllowAllHostnameVerifier());
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public Socket createSocket() throws IOException {
return mFactory.createSocket();
}
@Override
public Socket createSocket(Socket socket, String s, int i, boolean flag)
throws IOException {
return mFactory.createSocket(socket, s, i, flag);
}
}
}
我从MainActivity第44行收到此错误:
11-12 08:00:52.671 2294-2294/com.nicu.bogdan.lolstats E/AndroidRuntime: FATAL EXCEPTION: main
11-12 08:00:52.671 2294-2294/com.nicu.bogdan.lolstats E/AndroidRuntime: Process: com.nicu.bogdan.lolstats, PID: 2294
11-12 08:00:52.671 2294-2294/com.nicu.bogdan.lolstats E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nicu.bogdan.lolstats/com.nicu.bogdan.lolstats.MainActivity}: android.os.NetworkOnMainThreadException
非常感谢任何形式的帮助。
答案 0 :(得分:2)
如异常所述(NetworkOnMainThreadException)。不要在主线程中启动http请求。相反,请使用AsyncTask:http://developer.android.com/reference/android/os/AsyncTask.html
答案 1 :(得分:0)
//Thread policy for internet access in onCreate()
val SDK_INT = android.os.Build.VERSION.SDK_INT
if (SDK_INT > 8) {
val policy = StrictMode.ThreadPolicy.Builder()
.permitAll().build()
StrictMode.setThreadPolicy(policy)
}
button.setOnClickListener({
tv.setText("Clicked");
progress_bar.visibility = View.VISIBLE
// Kotlin + HttpURLConnection
val connection = URL("example.com").openConnection() as HttpURLConnection
connection.connect()
println(connection.responseCode)
println(connection.getHeaderField("Content-Type"))
val text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
<p>
//suppose sample data from http get calls
println(text) //sample data output
//setting text in txt view for demo.
tv.setText(text)
//optional block
//response to pojo work . following statement may be different in your case plz do as per your data
val gson = Gson() //gson object
val list1 = gson.fromJson<List<Product>>(text)
//convert/store response data to kotlin data class Product
println("Saved Data "+list1.size) //how much data saved
val s=list1.size; //size of collection
//printing saved data in pojo class
for (i in 0..s-1) {
//printing list from loop
println("Products Data : $list1.get(i).sku $list1.get(i).position $list1.get(i).category_id")
}
// end of optional block
progress_bar.visibility = View.GONE; //hide progress bar
}) //end of button event
//add following library in build.gradle module:app
<p>
compile 'com.beust:klaxon:0.30'
compile 'com.github.salomonbrys.kotson:kotson:2.5.0'
for more details
http://iotwebplanet.com/learn/call-webservice-kotlin-android/
</p>
/*
[
{"sku":"00012","position":1,"category_id":"6"},
{"sku":"00077","position":1,"category_id":"6"},
{"sku":"00072","position":1,"category_id":"6"},
{"sku":"00032","position":1,"category_id":"6"},
{"sku":"00074","position":1,"category_id":"6"},
{"sku":"00078","position":1,"category_id":"6"}
]
*/ </p>