如何在android中调用Https Rest服务

我正在尝试调用一个应该返回Json的Https服务。 但是,我无法正确设置连接。 我已经使用了这个主题的“正确”答案的代码: 如何在Android中调用https web服务

这里是我的代码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 

任何形式的帮助,非常感谢。

像例外说的那样做(NetworkOnMainThreadException)。 不要在主线程中启动http请求。 相反,使用AsyncTask: http : //developer.android.com/reference/android/os/AsyncTask.html

  //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>