original source : Retrofit Android Tutorial using Kotlin with RESTful We
https://www.youtube.com/playlist?list=PLlxmoA0rQ-LzEmWs4T99j2w6VnaQVGEtR

본격적인 내용은 3부터 이며 중간 중간 빨리 감으면서 보면된다.

대부분 10분 이내이다. 각 내용이 간결하고 명확하고 기본개념 잡기에 좋다.

아래는 android를 개발하면서 사용가능한 http libraries에 대해 소개하고 있다.

image
image
image
image

.

.

.

image
image

.

.

구성3개중에 service builder 부분 작성법

image

.

.

구성3개중에 interface 부분 작성법

image

.

.

interceptor를 위한 내용

image
image

service builder 에 추가한다.

.

.

image
image

.

.

image

위에서 getDestination()함수에 id parameter를 유의해서 본다.

image

destinationService.getDestination()함수에 id parameter를 전달함에 유의해서 본다.

.

.

query string 1개변수

image

.

.

query string 2개 변수

image

.

.

query string에 여러개의 변수를 전달해야 하는 경우 HashMap을 이용할수 있다.

image
image

.

.

path parameter, query parameter 둘다 사용한 경우

image

.

.

post시에 data 를 server에 전달하는 방법은 크게 json, formurlencoded 2가지 이다.

image
image
image
image

.

.

image
image

.

.

image

.

.

request에 header를 추가하는 방법

방법은 두가지이다. 상단에 hardcoded된 것과 함수 constructor에 dynamic하게 정의 되는 방법

image

.

.

다이나믹하게 정의 되는 경우 parameter로 전달된다. constructor에 전달되므로

image

.

.

interceptors의 다양한 사용예

image

.

.

사용자 정의 interceptor의 예

image

위의 과정을 아래와 같이 interceptor에 넣을수 있다.

image
image

.

.

image

timeout시에 onFailure함수가 호출된다.

image

.

.

request를 cancel하는 방법

image
image

original source : https://youtu.be/l5vPmxyWboM

InputStream 의 method mark() , reset()에 대하여

http://esus.com/java-inputstream-mark-reset/

==========================================================

.

.

==========================================================

.

.

이 강의의 예제 프로젝트에서 ImageRequest는 이전 강의에서 만든 NetworkRequest를 extends해서 사용한다.

==========================================================

.

.

==========================================================

.

.

ListView사용시 재활용되는 view때문에 발생하는 문제를 보여주고 있다.

==========================================================

.

.

original source : https://youtu.be/bJb6qJ5FrtU

image

===========================================================

image

networkinfo는 conncetiviymanager에서 getActiveNetworkInfo를 통해 얻는다.

===========================================================

image

===========================================================

image

===========================================================

image

requestRouteToHost를 통해 실제 host까지의 network가 연결되어 있는지를 확인할수 있다.

===========================================================

image

network 변화를 감지하는 receiver를 만들수 있다. 이때 발생하는 이벤트의 이름은 CONNECTIVITY_ACTION이다. 이 이벤트는 manifest의 intent-filter로 설정하면 감지할수 없고 registerReceiver()를 통해 코드로 등록되어야 한다. 

===========================================================

image

CONNECTIVITY_ACTION 이벤트를 감지한 receiver에서 전달되어 들어오는 intent에서 얻을수 있는 추가 정보를 설명하고 있다.

===========================================================

image

original source : https://developer.android.com/training/wearables/data-layer/network-access.html

Network Access and Syncing

With Android Wear 2.0, a watch can communicate with a network directly.

This direct network access replaces the use (in Wear 1.x) of the Data Layer API for connecting to a network .

Network Access

watch’s network traffic generally is proxied through the phone. But when a phone is unavailable, Wi-Fi and cellular networks are used, depending on the hardware. The Wear platform handles transitions between networks.

You can use protocols such as HTTP, TCP, and UDP. However, the android.webkit APIs (including the CookieManager class) are not available. You can use cookies by reading and writing headers on requests and responses.

참고사항

  • The JobScheduler API for asynchronous jobs, including polling at regular intervals (described below)
  • Multi-networking APIs if you need to connect to specific network types; see Multiple Network Connections

High-bandwidth Network Access

The Android Wear platform manages network connectivity.

The platform chooses the default, active network by balancing two factors:

  • The need for long battery life
  • The need for network bandwidth

            Acquiring a High-Bandwidth Network

high-bandwidth network가 항상 사용가능한게 아니므로

high-bandwidth network 가 필요한 경우아래의 과정을 거쳐야 한다. 

  1. Check for an active network, and if there is one, check its bandwidth.
  2. If there isn’t an active network, or its bandwidth is insufficient, request access to an unmetered Wi-Fi or cellular network.

ConnectivityManager class 를 사용하여 네트워크가 있는지 밴드크기 어떤지 확인가능하다. 

int MIN_BANDWIDTH_KBPS = 320;
mConnectivityManager =
 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = mConnectivityManager.getActiveNetwork();

if (activeNetwork != null) {
 int bandwidth =
   mConnectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();

 if (bandwidth < MIN_BANDWIDTH_KBPS) {
   // Request a high-bandwidth network
 }
} else {
 // You already are on a high-bandwidth network, so start your network request
}

You can request an unmetered, high-bandwidth network using the ConnectivityManager.

When the network is ready (e.g., the device’s Wi-Fi radio connects to a saved network), the onAvailable() method of your NetworkCallback instance is called. If a suitable network is not found, the onAvailable() method is not called. Therefore, you should time-out your request manually; see Waiting for Network Availability.

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
 @Override
 public void onAvailable(Network network) {
   if (bindProcessToNetwork(network)) {
     // socket connections will now use this network
   } else {
     // app doesn't have android.permission.INTERNET permission
   }
 }
};

NetworkRequest request = new NetworkRequest.Builder()
 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
 .build();

mConnectivityManager.requestNetwork(request, mNetworkCallback);

       Releasing the Network

사용이 끝난 network는 release해야 한다. 

mConnectivityManager.bindProcessToNetwork(null);
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);

또 이작업은 

activity’s onStop() method 안에서도 실행되어야 한다.

       Waiting for Network Availability

if a watch cannot connect to a network, the onAvailable() method of your NetworkCallback instance is not called. Therefore, you should time-out the request after a predetermined length of time and release any associated resources.

int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
long NETWORK_CONNECTIVITY_TIMEOUT_MS = 10000

mHandler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
   switch (msg.what) {
     case MESSAGE_CONNECTIVITY_TIMEOUT:
       // unregister the network
       break;
   }
 }
};

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
 @Override
 public void onAvailable(Network network) {
   mHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
   ...
 }
};

mConnectivityManager.requestNetwork(request, mNetworkCallback);

mHandler.sendMessageDelayed(
 mHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT),
 NETWORK_CONNECTIVITY_TIMEOUT_MS);

       

Monitoring the Network State

mNetworkCallback = ConnectivityManager.NetworkCallback {
 @Override
 public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
   int bandwidth =
     mConnectivityManager.getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();

     if (bandwidth < MIN_BANDWIDTH.KBPS) {
       // handle insufficient network bandwidth
     }
 }

 @Override
 public void onLost(Network network) {
   // handle network loss
 }
}

       

Launching the Wi-Fi Settings Activity

사용자가 저장한 wi-fi가 없거나 접근 불가능한 경우 사용자를 wi-fi 설정 activity로 이동시킬수 있다.

context.startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));

Cloud Messaging

For sending notifications, apps can directly use Firebase Cloud Messaging (FCM)

By default, notifications are bridged (shared) from a phone app to a watch. If you have a standalone Wear app and a corresponding phone app, duplicate notifications can occur.

Using Background Services

You should schedule jobs with the JobScheduler API, which enables your app to register for Doze-safe code execution.

Jobs should use a JobInfo.Builder object to provide constraints and metadata.

  • To schedule a task that requires networking, use setRequiredNetworkType(int networkType), specifying NETWORK_TYPE_ANY or NETWORK_TYPE_UNMETERED; note that NETWORK_TYPE_UNMETERED is for large data transfers while NETWORK_TYPE_ANY is for small transfers
  • To schedule a task while charging, use setRequiresCharging(boolean requiresCharging)
  • To specify that a device is idle for a task, use setRequiresDeviceIdle(boolean requiresDeviceIdle); this method is useful for lower-priority background work or synchronization, especially when used with setRequiresCharging

Note that some low-bandwidth networks, such as Bluetooth LE, are considered meter

Scheduling with constraints

You can use the builder method setExtras to attach a bundle of app-specific metadata to the job request. When your job executes, this bundle is provided to your job service. Note the MY_JOB_ID value passed to the JobInfo.Builder constructor. This MY_JOB_ID value is an app-provided identifier. Subsequent calls to cancel, and subsequent jobs created with that same value, will update the existing job.

JobInfo jobInfo = new JobInfo.Builder(MY_JOB_ID,
       new ComponentName(this, MyJobService.class))
       .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
       .setRequiresCharging(true)
       .setExtras(extras)
       .build();
((JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE))
       .schedule(jobInfo);

아래는 위의 작업을 서비스하는 부분설명.

JobParameters object is passed into the onStartJobmethod. The JobParameters object enables you to get the job ID value along with any extras bundle provided when scheduling the job.

The onStartJobmethod is called on the main application thread, and therefore any expensive logic should be run from a separate thread .

When work is complete, you would call the jobFinished method to notify JobScheduler that the task is done.

public class MyJobService extends JobService {
   @Override public boolean onStartJob(JobParameters params) {
       new JobAsyncTask().execute(params);
       return true;
   }

   private class JobAsyncTask extends AsyncTask

original source : https://developer.android.com/training/wearables/data-layer/network-access.html

Network Access and Syncing

With Android Wear 2.0, a watch can communicate with a network directly.

This direct network access replaces the use (in Wear 1.x) of the Data Layer API for connecting to a network .

Network Access

watch’s network traffic generally is proxied through the phone. But when a phone is unavailable, Wi-Fi and cellular networks are used, depending on the hardware. The Wear platform handles transitions between networks.

You can use protocols such as HTTP, TCP, and UDP. However, the android.webkit APIs (including the CookieManager class) are not available. You can use cookies by reading and writing headers on requests and responses.

참고사항

  • The JobScheduler API for asynchronous jobs, including polling at regular intervals (described below)
  • Multi-networking APIs if you need to connect to specific network types; see Multiple Network Connections

High-bandwidth Network Access

The Android Wear platform manages network connectivity.

The platform chooses the default, active network by balancing two factors:

  • The need for long battery life
  • The need for network bandwidth

            Acquiring a High-Bandwidth Network

high-bandwidth network가 항상 사용가능한게 아니므로

high-bandwidth network 가 필요한 경우아래의 과정을 거쳐야 한다. 

  1. Check for an active network, and if there is one, check its bandwidth.
  2. If there isn’t an active network, or its bandwidth is insufficient, request access to an unmetered Wi-Fi or cellular network.

ConnectivityManager class 를 사용하여 네트워크가 있는지 밴드크기 어떤지 확인가능하다. 

int MIN_BANDWIDTH_KBPS = 320;
mConnectivityManager =
 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = mConnectivityManager.getActiveNetwork();

if (activeNetwork != null) {
 int bandwidth =
   mConnectivityManager.getNetworkCapabilities(activeNetwork).getLinkDownstreamBandwidthKbps();

 if (bandwidth < MIN_BANDWIDTH_KBPS) {
   // Request a high-bandwidth network
 }
} else {
 // You already are on a high-bandwidth network, so start your network request
}

You can request an unmetered, high-bandwidth network using the ConnectivityManager.

When the network is ready (e.g., the device’s Wi-Fi radio connects to a saved network), the onAvailable() method of your NetworkCallback instance is called. If a suitable network is not found, the onAvailable() method is not called. Therefore, you should time-out your request manually; see Waiting for Network Availability.

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
 @Override
 public void onAvailable(Network network) {
   if (bindProcessToNetwork(network)) {
     // socket connections will now use this network
   } else {
     // app doesn't have android.permission.INTERNET permission
   }
 }
};

NetworkRequest request = new NetworkRequest.Builder()
 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
 .build();

mConnectivityManager.requestNetwork(request, mNetworkCallback);

       Releasing the Network

사용이 끝난 network는 release해야 한다. 

mConnectivityManager.bindProcessToNetwork(null);
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);

또 이작업은 

activity’s onStop() method 안에서도 실행되어야 한다.

       Waiting for Network Availability

if a watch cannot connect to a network, the onAvailable() method of your NetworkCallback instance is not called. Therefore, you should time-out the request after a predetermined length of time and release any associated resources.

int MESSAGE_CONNECTIVITY_TIMEOUT = 1;
long NETWORK_CONNECTIVITY_TIMEOUT_MS = 10000

mHandler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
   switch (msg.what) {
     case MESSAGE_CONNECTIVITY_TIMEOUT:
       // unregister the network
       break;
   }
 }
};

mNetworkCallback = new ConnectivityManager.NetworkCallback() {
 @Override
 public void onAvailable(Network network) {
   mHandler.removeMessages(MESSAGE_CONNECTIVITY_TIMEOUT);
   ...
 }
};

mConnectivityManager.requestNetwork(request, mNetworkCallback);

mHandler.sendMessageDelayed(
 mHandler.obtainMessage(MESSAGE_CONNECTIVITY_TIMEOUT),
 NETWORK_CONNECTIVITY_TIMEOUT_MS);

       

Monitoring the Network State

mNetworkCallback = ConnectivityManager.NetworkCallback {
 @Override
 public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
   int bandwidth =
     mConnectivityManager.getNetworkCapabilities(network).getLinkDownstreamBandwidthKbps();

     if (bandwidth < MIN_BANDWIDTH.KBPS) {
       // handle insufficient network bandwidth
     }
 }

 @Override
 public void onLost(Network network) {
   // handle network loss
 }
}

       

Launching the Wi-Fi Settings Activity

사용자가 저장한 wi-fi가 없거나 접근 불가능한 경우 사용자를 wi-fi 설정 activity로 이동시킬수 있다.

context.startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));

Cloud Messaging

For sending notifications, apps can directly use Firebase Cloud Messaging (FCM)

By default, notifications are bridged (shared) from a phone app to a watch. If you have a standalone Wear app and a corresponding phone app, duplicate notifications can occur.

Using Background Services

You should schedule jobs with the JobScheduler API, which enables your app to register for Doze-safe code execution.

Jobs should use a JobInfo.Builder object to provide constraints and metadata.

  • To schedule a task that requires networking, use setRequiredNetworkType(int networkType), specifying NETWORK_TYPE_ANY or NETWORK_TYPE_UNMETERED; note that NETWORK_TYPE_UNMETERED is for large data transfers while NETWORK_TYPE_ANY is for small transfers
  • To schedule a task while charging, use setRequiresCharging(boolean requiresCharging)
  • To specify that a device is idle for a task, use setRequiresDeviceIdle(boolean requiresDeviceIdle); this method is useful for lower-priority background work or synchronization, especially when used with setRequiresCharging

Note that some low-bandwidth networks, such as Bluetooth LE, are considered meter

Scheduling with constraints

You can use the builder method setExtras to attach a bundle of app-specific metadata to the job request. When your job executes, this bundle is provided to your job service. Note the MY_JOB_ID value passed to the JobInfo.Builder constructor. This MY_JOB_ID value is an app-provided identifier. Subsequent calls to cancel, and subsequent jobs created with that same value, will update the existing job.

JobInfo jobInfo = new JobInfo.Builder(MY_JOB_ID,
       new ComponentName(this, MyJobService.class))
       .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
       .setRequiresCharging(true)
       .setExtras(extras)
       .build();
((JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE))
       .schedule(jobInfo);

아래는 위의 작업을 서비스하는 부분설명.

JobParameters object is passed into the onStartJobmethod. The JobParameters object enables you to get the job ID value along with any extras bundle provided when scheduling the job.

The onStartJobmethod is called on the main application thread, and therefore any expensive logic should be run from a separate thread .

When work is complete, you would call the jobFinished method to notify JobScheduler that the task is done.

public class MyJobService extends JobService {
   @Override public boolean onStartJob(JobParameters params) {
       new JobAsyncTask().execute(params);
       return true;
   }

   private class JobAsyncTask extends AsyncTask

Java IO: Networking