Android10.0(Q) 网络自动校时bug修改

简介: Android10.0(Q) 网络自动校时bug修改

问题现象


联网后系统时间依旧显示不对,和系统校时服务器有关系,之前低版本也修改过这个问题来着


修改方法


和之前低版本比对发现,以前的 NetworkTimeUpdateService 已经更名为 NewNetworkTimeUpdateService,而且代码变动不小,根据之前修改问题不大。

frameworks/base/services/core/java/com/android/server/NewNetworkTimeUpdateService.java

import java.io.PrintWriter;
//M: For multiple NTP server retry
import java.util.ArrayList;
import android.os.AsyncTask;
import android.net.NetworkInfo;
+
 /**
  * Monitors the network time and updates the system time if it is out of sync
  * and there hasn't been any NITZ update from the carrier recently.
@@ -98,6 +103,18 @@ public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUp
     // connection to happen.
     private int mTryAgainCounter;
     //UGG add ,add ntp servers [S]                                         
    private static final String[] NTPSERVERLIST =  new String[]{
                                            "s1b.time.edu.cn",
                                            "ntp3.aliyun.com",
                                            "ntp4.aliyun.com",
                                            "ntp5.aliyun.com",                                
                                             };                                        
    private AsyncTask ntpTimeTask;  
    private boolean isNtpTimeTaskRunning;  
    //UGG add ,add ntp servers [E] 
     public NewNetworkTimeUpdateService(Context context) {
         mContext = context;
         mTime = NtpTrustedTime.getInstance(context);
@@ -138,6 +155,7 @@ public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUp
     private void registerForTelephonyIntents() {
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         mContext.registerReceiver(mNitzReceiver, intentFilter);
     }
@@ -249,10 +267,49 @@ public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUp
             if (DBG) Log.d(TAG, "Received " + action);
             if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
                 mNitzTimeSetTime = SystemClock.elapsedRealtime();
            }else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
                //UGG add ,add ntp servers [S]                                         
                NetworkInfo info = mCM.getActiveNetworkInfo();  
                if(info != null && info.isAvailable()) {
                    String name = info.getTypeName();
                    Log.d(TAG, "current networkType" + name);
                    if(!isNtpTimeTaskRunning){
                        isNtpTimeTaskRunning=true;
                        new NtpTimeThread().start();
                    }
                } else {
                    Log.d(TAG, "no available network");
                    // if(ntpTimeTask!=null){
                    //     ntpTimeTask.cancel(true);
                    // }
                }
                //UGG add ,add ntp servers [E]                                         
             }
         }
     };
    //UGG add ,add ntp servers [S]                                         
   public class NtpTimeThread extends Thread {
        @Override
        public void run() {
            super.run();
            for(int i=0;i<NTPSERVERLIST.length;i++){
                try{
                    sleep(1000);
                    boolean result=GetNtpTIme.GetLocalNtpTime(NTPSERVERLIST[i]);
                    Log.i(TAG,"NtpTimeThread result "+result);
                        if(result){
                            break;
                        }
                    }catch(Exception e){
                    }
            }
            isNtpTimeTaskRunning=false;
        }
    }
    //UGG add ,add ntp servers [S]    
     /** Handler to do the network accesses on */
     private class MyHandler extends Handler {

同级目录下新增 GetNtpTIme.java 和 NtpMessage.java

frameworks/base/services/core/java/com/android/server/GetNtpTIme.java


package com.android.server;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;
import java.util.Date;
import android.os.SystemClock;
import android.util.Log;
public class GetNtpTIme {
  private static String TAG="NetworkTimeUpdateService.GetNtpTIme";
  public static boolean GetLocalNtpTime(String ntpSvrIP) {
    boolean res = false;
    int retry = 0;
    int port = 123;
    int timeout = 10000;
    // get the address and NTP address request
    InetAddress ipv4Addr = null;
    try {
      if(ntpSvrIP==null){
        ipv4Addr = InetAddress.getByName("s1b.time.edu.cn");
      }else{
        ipv4Addr = InetAddress.getByName(ntpSvrIP);
      }
      Log.d(TAG, "ntpSvrIP : " + ntpSvrIP+", ipv4Addr : "+ipv4Addr);
    } catch (UnknownHostException e1) {
      e1.printStackTrace();
    }
    int serviceStatus = -1;
    DatagramSocket socket = null;
    long responseTime = -1;
    try {
      socket = new DatagramSocket();
      socket.setSoTimeout(timeout); // will force the
      // InterruptedIOException
      for (int attempts = 0; attempts <= retry && serviceStatus != 1; attempts++) {
        try {
          // Send NTP request
          byte[] data = new NtpMessage().toByteArray();
          DatagramPacket outgoing = new DatagramPacket(data,
              data.length, ipv4Addr, port);
          long sentTime = System.currentTimeMillis();
          socket.send(outgoing);
          // Get NTP Response
          DatagramPacket incoming = new DatagramPacket(data,
              data.length);
          socket.receive(incoming);
          responseTime = System.currentTimeMillis() - sentTime;
          double destinationTimestamp = (System.currentTimeMillis() / 1000.0) + 2208988800.0;
          // 这里要加2208988800,是因为获得到的时间是格林尼治时间,所以要变成东八区的时间,否则会与与北京时间有8小时的时差
          // Validate NTP Response
          // IOException thrown if packet does not decode as expected.
          NtpMessage msg = new NtpMessage(incoming.getData());
          double localClockOffset = ((msg.receiveTimestamp - msg.originateTimestamp) + (msg.transmitTimestamp - destinationTimestamp)) / 2;
          Log.d(TAG,"poll: valid NTP request received the local clock offset is "
                  + localClockOffset + ", responseTime= "
                  + responseTime + "ms");
          Log.d(TAG, "poll: NTP message : " + msg.toString());
          SystemClock.setCurrentTimeMillis(msg.GetCurrentMS(msg.transmitTimestamp));
          serviceStatus = 1;
          res = true;
        } catch (Exception ex1) {
          // Ignore, no response received.
          Log.d(TAG, "InterruptedIOException: "
          + ex1.toString());
        }
      }
    } catch (NoRouteToHostException e) {
      Log.d(TAG, "No route to host exception for address: "
          + ipv4Addr);
    } catch (ConnectException e) {
      // Connection refused. Continue to retry.
      e.fillInStackTrace();
      Log.d(TAG, "Connection exception for address: " + ipv4Addr);
    } catch (IOException ex) {
      ex.fillInStackTrace();
      Log.d(TAG, "IOException while polling address: " + ipv4Addr);
    } finally {
      if (socket != null){
        socket.close();
        Log.d(TAG, "ntp address: " + ipv4Addr+" res:"+String.valueOf(res));
        return res;
      }
    }
    // Store response time if available
    //
    if (serviceStatus == 1) {
      Log.d(TAG, "responsetime==" + responseTime);
    }
    return res;
  }
}

frameworks/base/services/core/java/com/android/server/NtpMessage.java

package com.android.server;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class NtpMessage {  
    /** *//** 
     * This is a two-bit code warning of an impending leap second to be 
     * inserted/deleted in the last minute of the current day. It''s values may 
     * be as follows: 
     *  
     * Value Meaning ----- ------- 0 no warning 1 last minute has 61 seconds 2 
     * last minute has 59 seconds) 3 alarm condition (clock not synchronized) 
     */  
    public byte leapIndicator = 0;  
    /** *//** 
     * This value indicates the NTP/SNTP version number. The version number is 3 
     * for Version 3 (IPv4 only) and 4 for Version 4 (IPv4, IPv6 and OSI). If 
     * necessary to distinguish between IPv4, IPv6 and OSI, the encapsulating 
     * context must be inspected. 
     */  
    public byte version = 3;  
    /** *//** 
     * This value indicates the mode, with values defined as follows: 
     *  
     * Mode Meaning ---- ------- 0 reserved 1 symmetric active 2 symmetric 
     * passive 3 client 4 server 5 broadcast 6 reserved for NTP control message 
     * 7 reserved for private use 
     *  
     * In unicast and anycast modes, the client sets this field to 3 (client) in 
     * the request and the server sets it to 4 (server) in the reply. In 
     * multicast mode, the server sets this field to 5 (broadcast). 
     */  
    public byte mode = 0;  
    /** *//** 
     * This value indicates the stratum level of the local clock, with values 
     * defined as follows: 
     *  
     * Stratum Meaning ---------------------------------------------- 0 
     * unspecified or unavailable 1 primary reference (e.g., radio clock) 2-15 
     * secondary reference (via NTP or SNTP) 16-255 reserved 
     */  
    public short stratum = 0;  
    /** *//** 
     * This value indicates the maximum interval between successive messages, in 
     * seconds to the nearest power of two. The values that can appear in this 
     * field presently range from 4 (16 s) to 14 (16284 s); however, most 
     * applications use only the sub-range 6 (64 s) to 10 (1024 s). 
     */  
    public byte pollInterval = 0;  
    /** *//** 
     * This value indicates the precision of the local clock, in seconds to the 
     * nearest power of two. The values that normally appear in this field 
     * range from -6 for mains-frequency clocks to -20 for microsecond clocks 
     * found in some workstations. 
     */  
    public byte precision = 0;  
    /** *//** 
     * This value indicates the total roundtrip delay to the primary reference 
     * source, in seconds. Note that this variable can take on both positive and 
     * negative values, depending on the relative time and frequency offsets. 
     * The values that normally appear in this field range from negative values 
     * of a few milliseconds to positive values of several hundred milliseconds. 
     */  
    public double rootDelay = 0;  
    /** *//** 
     * This value indicates the nominal error relative to the primary reference 
     * source, in seconds. The values that normally appear in this field range 
     * from 0 to several hundred milliseconds. 
     */  
    public double rootDispersion = 0;  
    /** *//** 
     * This is a 4-byte array identifying the particular reference source. In 
     * the case of NTP Version 3 or Version 4 stratum-0 (unspecified) or 
     * stratum-1 (primary) servers, this is a four-character ASCII string, left 
     * justified and zero padded to 32 bits. In NTP Version 3 secondary servers, 
     * this is the 32-bit IPv4 address of the reference source. In NTP Version 4 
     * secondary servers, this is the low order 32 bits of the latest transmit 
     * timestamp of the reference source. NTP primary (stratum 1) servers should 
     * set this field to a code identifying the external reference source 
     * according to the following list. If the external reference is one of 
     * those listed, the associated code should be used. Codes for sources not 
     * listed can be contrived as appropriate. 
     *  
     * Code External Reference Source ---- ------------------------- LOCL 
     * uncalibrated local clock used as a primary reference for a subnet without 
     * external means of synchronization PPS atomic clock or other 
     * pulse-per-second source individually calibrated to national standards 
     * ACTS NIST dialup modem service USNO USNO modem service PTB PTB (Germany) 
     * modem service TDF Allouis (France) Radio 164 kHz DCF Mainflingen 
     * (Germany) Radio 77.5 kHz MSF Rugby (UK) Radio 60 kHz WWV Ft. Collins (US) 
     * Radio 2.5, 5, 10, 15, 20 MHz WWVB Boulder (US) Radio 60 kHz WWVH Kaui 
     * Hawaii (US) Radio 2.5, 5, 10, 15 MHz CHU Ottawa (Canada) Radio 3330, 
     * 7335, 14670 kHz LORC LORAN-C radionavigation system OMEG OMEGA 
     * radionavigation system GPS Global Positioning Service GOES Geostationary 
     * Orbit Environment Satellite 
     */  
    public byte[] referenceIdentifier = { 0, 0, 0, 0 };  
    /** *//** 
     * This is the time at which the local clock was last set or corrected, in 
     * seconds since 00:00 1-Jan-1900. 
     */  
    public double referenceTimestamp = 0;  
    /** *//** 
     * This is the time at which the request departed the client for the server, 
     * in seconds since 00:00 1-Jan-1900. 
     */  
    public double originateTimestamp = 0;  
    /** *//** 
     * This is the time at which the request arrived at the server, in seconds 
     * since 00:00 1-Jan-1900. 
     */  
    public double receiveTimestamp = 0;  
    /** *//** 
     * This is the time at which the reply departed the server for the client, 
     * in seconds since 00:00 1-Jan-1900. 
     */  
    public double transmitTimestamp = 0;  
    /** *//** 
     * Constructs a new NtpMessage from an array of bytes. 
     */  
    public NtpMessage(byte[] array) {  
        // See the packet format diagram in RFC 2030 for details  
        leapIndicator = (byte) ((array[0] >> 6) & 0x3);  
        version = (byte) ((array[0] >> 3) & 0x7);  
        mode = (byte) (array[0] & 0x7);  
        stratum = unsignedByteToShort(array[1]);  
        pollInterval = array[2];  
        precision = array[3];  
        rootDelay = (array[4] * 256.0) + unsignedByteToShort(array[5]) + (unsignedByteToShort(array[6]) / 256.0) + (unsignedByteToShort(array[7]) / 65536.0);  
        rootDispersion = (unsignedByteToShort(array[8]) * 256.0) + unsignedByteToShort(array[9]) + (unsignedByteToShort(array[10]) / 256.0) + (unsignedByteToShort(array[11]) / 65536.0);  
        referenceIdentifier[0] = array[12];  
        referenceIdentifier[1] = array[13];  
        referenceIdentifier[2] = array[14];  
        referenceIdentifier[3] = array[15];  
        referenceTimestamp = decodeTimestamp(array, 16);  
        originateTimestamp = decodeTimestamp(array, 24);  
        receiveTimestamp = decodeTimestamp(array, 32);  
        transmitTimestamp = decodeTimestamp(array, 40);  
    }  
    /** *//** 
     * Constructs a new NtpMessage 
     */  
    public NtpMessage(byte leapIndicator, byte version, byte mode, short stratum, byte pollInterval, byte precision, double rootDelay, double rootDispersion, byte[] referenceIdentifier, double referenceTimestamp, double originateTimestamp, double receiveTimestamp, double transmitTimestamp) {  
        // ToDo: Validity checking  
        this.leapIndicator = leapIndicator;  
        this.version = version;  
        this.mode = mode;  
        this.stratum = stratum;  
        this.pollInterval = pollInterval;  
        this.precision = precision;  
        this.rootDelay = rootDelay;  
        this.rootDispersion = rootDispersion;  
        this.referenceIdentifier = referenceIdentifier;  
        this.referenceTimestamp = referenceTimestamp;  
        this.originateTimestamp = originateTimestamp;  
        this.receiveTimestamp = receiveTimestamp;  
        this.transmitTimestamp = transmitTimestamp;  
    }  
    /** *//** 
     * Constructs a new NtpMessage in client -> server mode, and sets the 
     * transmit timestamp to the current time. 
     */  
    public NtpMessage() {  
        // Note that all the other member variables are already set with  
        // appropriate default values.  
        this.mode = 3;  
        this.transmitTimestamp = (System.currentTimeMillis() / 1000.0) + 2208988800.0;  
    }  
    /** *//** 
     * This method constructs the data bytes of a raw NTP packet. 
     */  
    public byte[] toByteArray() {  
        // All bytes are automatically set to 0  
        byte[] p = new byte[48];  
        p[0] = (byte) (leapIndicator << 6 | version << 3 | mode);  
        p[1] = (byte) stratum;  
        p[2] = (byte) pollInterval;  
        p[3] = (byte) precision;  
        // root delay is a signed 16.16-bit FP, in Java an int is 32-bits  
        int l = (int) (rootDelay * 65536.0);  
        p[4] = (byte) ((l >> 24) & 0xFF);  
        p[5] = (byte) ((l >> 16) & 0xFF);  
        p[6] = (byte) ((l >> 8) & 0xFF);  
        p[7] = (byte) (l & 0xFF);  
        // root dispersion is an unsigned 16.16-bit FP, in Java there are no  
        // unsigned primitive types, so we use a long which is 64-bits  
        long ul = (long) (rootDispersion * 65536.0);  
        p[8] = (byte) ((ul >> 24) & 0xFF);  
        p[9] = (byte) ((ul >> 16) & 0xFF);  
        p[10] = (byte) ((ul >> 8) & 0xFF);  
        p[11] = (byte) (ul & 0xFF);  
        p[12] = referenceIdentifier[0];  
        p[13] = referenceIdentifier[1];  
        p[14] = referenceIdentifier[2];  
        p[15] = referenceIdentifier[3];  
        encodeTimestamp(p, 16, referenceTimestamp);  
        encodeTimestamp(p, 24, originateTimestamp);  
        encodeTimestamp(p, 32, receiveTimestamp);  
        encodeTimestamp(p, 40, transmitTimestamp);  
        return p;  
    }  
    /** *//** 
     * Returns a string representation of a NtpMessage 
     */  
    public String toString() {  
        String precisionStr = new DecimalFormat("0.#E0").format(Math.pow(2, precision));  
        return "Leap indicator: " + leapIndicator + " " + "Version: " + version + " " + "Mode: " + mode + " " + "Stratum: " + stratum + " " + "Poll: " + pollInterval + " " + "Precision: " + precision + " (" + precisionStr + " seconds) " + "Root delay: " + new DecimalFormat("0.00").format(rootDelay * 1000) + " ms " + "Root dispersion: " + new DecimalFormat("0.00").format(rootDispersion * 1000) + " ms " + "Reference identifier: " + referenceIdentifierToString(referenceIdentifier, stratum, version) + " " + "Reference timestamp: " + timestampToString(referenceTimestamp) + " " + "Originate timestamp: " + timestampToString(originateTimestamp) + " " + "Receive timestamp:   " + timestampToString(receiveTimestamp) + " " + "Transmit timestamp: " + timestampToString(transmitTimestamp);  
    }  
    /** *//** 
     * Converts an unsigned byte to a short. By default, Java assumes that a 
     * byte is signed. 
     */  
    public static short unsignedByteToShort(byte b) {  
        if ((b & 0x80) == 0x80)  
            return (short) (128 + (b & 0x7f));  
        else  
            return (short) b;  
    }  
    /** *//** 
     * Will read 8 bytes of a message beginning at <code>pointer</code> and 
     * return it as a double, according to the NTP 64-bit timestamp format. 
     */  
    public static double decodeTimestamp(byte[] array, int pointer) {  
        double r = 0.0;  
        for (int i = 0; i < 8; i++) {  
            r += unsignedByteToShort(array[pointer + i]) * Math.pow(2, (3 - i) * 8);  
        }  
        return r;  
    }  
    /** *//** 
     * Encodes a timestamp in the specified position in the message 
     */  
    public static void encodeTimestamp(byte[] array, int pointer, double timestamp) {  
        // Converts a double into a 64-bit fixed point  
        for (int i = 0; i < 8; i++) {  
            // 2^24, 2^16, 2^8, .. 2^-32  
            double base = Math.pow(2, (3 - i) * 8);  
            // Capture byte value  
            array[pointer + i] = (byte) (timestamp / base);  
            // Subtract captured value from remaining total  
            timestamp = timestamp - (double) (unsignedByteToShort(array[pointer + i]) * base);  
        }  
        // From RFC 2030: It is advisable to fill the non-significant  
        // low order bits of the timestamp with a random, unbiased  
        // bitstring, both to avoid systematic roundoff errors and as  
        // a means of loop detection and replay detection.  
        array[7] = (byte) (Math.random() * 255.0);  
    }  
    /** *//** 
     * Returns a timestamp (number of seconds since 00:00 1-Jan-1900) as a 
     * formatted date/time string. 
     */  
    public static String timestampToString(double timestamp) {  
        if (timestamp == 0)  
            return "0";  
        // timestamp is relative to 1900, utc is used by Java and is relative  
        // to 1970  
        double utc = timestamp - (2208988800.0);  
        // milliseconds  
        long ms = (long) (utc * 1000.0);  
        // date/time  
        String date = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss").format(new Date(ms));  
        // fraction  
        double fraction = timestamp - ((long) timestamp);  
        String fractionSting = new DecimalFormat(".000000").format(fraction);  
        return date + fractionSting;  
    }  
    public long GetCurrentMS(double timestamp){
        if (timestamp == 0)  
            return 0;  
        // timestamp is relative to 1900, utc is used by Java and is relative  
        // to 1970  
        double utc = timestamp - (2208988800.0);  
        // milliseconds  
        long ms = (long) (utc * 1000.0);  
        return ms;
    }
    /** *//** 
     * Returns a string representation of a reference identifier according to 
     * the rules set out in RFC 2030. 
     */  
    public static String referenceIdentifierToString(byte[] ref, short stratum, byte version) {  
        // From the RFC 2030:  
        // In the case of NTP Version 3 or Version 4 stratum-0 (unspecified)  
        // or stratum-1 (primary) servers, this is a four-character ASCII  
        // string, left justified and zero padded to 32 bits.  
        if (stratum == 0 || stratum == 1) {  
            return new String(ref);  
        }  
        // In NTP Version 3 secondary servers, this is the 32-bit IPv4  
        // address of the reference source.  
        else if (version == 3) {  
            return unsignedByteToShort(ref[0]) + "." + unsignedByteToShort(ref[1]) + "." + unsignedByteToShort(ref[2]) + "." + unsignedByteToShort(ref[3]);  
        }  
        // In NTP Version 4 secondary servers, this is the low order 32 bits  
        // of the latest transmit timestamp of the reference source.  
        else if (version == 4) {  
            return "" + ((unsignedByteToShort(ref[0]) / 256.0) + (unsignedByteToShort(ref[1]) / 65536.0) + (unsignedByteToShort(ref[2]) / 16777216.0) + (unsignedByteToShort(ref[3]) / 4294967296.0));  
        }  
        return "";  
    }  
}  



目录
相关文章
|
1月前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin协程优化网络请求处理
【2月更文挑战第30天】 在移动应用开发领域,网络请求的处理是影响用户体验的关键环节。针对Android平台,利用Kotlin协程能够极大提升异步任务处理的效率和简洁性。本文将探讨如何通过Kotlin协程优化Android应用中的网络请求处理流程,包括协程的基本概念、网络请求的异步执行以及错误处理等方面,旨在帮助开发者构建更加流畅和响应迅速的Android应用。
|
3月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
39 0
|
3月前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
22 0
|
4月前
|
XML Java Android开发
Android App开发网络通信中使用okhttp下载和上传图片、文件讲解及实战(超详细实现用户注册信息上传 附源码)
Android App开发网络通信中使用okhttp下载和上传图片、文件讲解及实战(超详细实现用户注册信息上传 附源码)
147 0
|
4天前
|
移动开发 Java Android开发
构建高效Android应用:采用Kotlin协程优化网络请求
【4月更文挑战第24天】 在移动开发领域,尤其是对于Android平台而言,网络请求是一个不可或缺的功能。然而,随着用户对应用响应速度和稳定性要求的不断提高,传统的异步处理方式如回调地狱和RxJava已逐渐显示出局限性。本文将探讨如何利用Kotlin协程来简化异步代码,提升网络请求的效率和可读性。我们将深入分析协程的原理,并通过一个实际案例展示如何在Android应用中集成和优化网络请求。
|
12天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
11 0
|
12天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
10 0
|
4月前
|
XML JSON Java
Android App网络通信中通过okhttp调用HTTP接口讲解及实战(包括GET、表单格式POST、JSON格式POST 附源码)
Android App网络通信中通过okhttp调用HTTP接口讲解及实战(包括GET、表单格式POST、JSON格式POST 附源码)
173 0
|
3月前
|
前端开发
elementui-upload组件自定义样式上传(upload中常用的属性,但是网络上却找不到教程)(解决bug删除之后再次上传会上传删除的图片)专注后端工程师的前端速成
elementui-upload组件自定义样式上传(upload中常用的属性,但是网络上却找不到教程)(解决bug删除之后再次上传会上传删除的图片)专注后端工程师的前端速成
68 0
|
3月前
|
JSON Java Android开发
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
24 0