AndroidP対応をしたので、そこで出た影響まとめ

## 最初に行うこと
1. buildSDKVersion/targetSdkVersionを28にあげる
2. supportLibraryを最新版にする  
最新版はmaven参照  
 (https://mvnrepository.com/artifact/com.android.support/support-v4)
3. ビルドをかける
 
---
## 以下、対応内容
### Canvasクラス周り
以下の変数が使えなくなっている

```
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
Canvas.FULL_COLOR_LAYER_SAVE_FLAG
```
#### 原因
`@removed`されているから(おそらく、Api27~28から)  
基本的には
`Canvas.ALL_SAVE_FLAG`を使え！とのこと

また、
```
Canvas.saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags);
```
がApi26からdeplicatedなので、

```
Canvas.saveLayer(@Nullable RectF bounds, @Nullable Paint paint);
```
こっちに変更。

---
### 古いOSSの突然の死
~~(使ってるこっちが悪いんですが・・・)~~  
こういうLogで落ちる()
```
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/ProtocolVersion;
```

#### 原因
Google曰く(https://developer.android.com/about/versions/pie/android-9.0-changes-all#apache-nonp)

>Apache HTTP client deprecation affects apps with non-standard ClassLoader
With Android 6.0, we removed support for the Apache HTTP client. This change has no effect on the great majority of apps that do not target Android 9 or higher. However, the change can affect certain apps that use a nonstandard ClassLoader structure, even if the apps do not target Android 9 or higher.  

>An app can be affected if it uses a non-standard ClassLoader that explicitly delegates to the system ClassLoader. These apps need to delegate to the app ClassLoader instead when looking for classes in org.apache.http.*. If they delegate to the system ClassLoader, the apps will fail on Android 9 or higher with a NoClassDefFoundError, because those classes are no longer known to the system ClassLoader. To prevent similar problems in the future, apps should in general load classes through the app ClassLoader rather than accessing the system ClassLoader directly.

↓Google先生曰く(翻訳)↓
>Android 6.0では、Apache HTTPクライアントのサポートを削除しました。 この変更は、Android 9以降をターゲットとしていない大部分のアプリには影響しません。 ただし、Android 9以降をターゲットにしていないアプリであっても、非標準ClassLoader構造を使用する特定のアプリに影響を与える可能性があります。

>システムClassLoaderに明示的に委譲する非標準ClassLoaderを使用すると、アプリケーションに影響を与えることがあります。 これらのアプリはorg.apache.http。*のクラスを探すときにアプリClassLoaderに委譲する必要があります。 彼らがシステムClassLoaderに委任すれば、NoClassDefFoundErrorを使ってAndroid 9以降でアプリケーションは失敗します。なぜなら、それらのクラスはもはやシステムのClassLoaderに知られていないからです。 将来的に同様の問題が発生するのを防ぐため、アプリはClassLoaderシステムに直接アクセスするのではなく、アプリClassLoaderを介してクラスをロードする必要があります。

##### 原因の詳細
- おそらく`ClassLoader`を継承した、`NewWoarkClassLoader`をアプリに委譲させないで(OSSが勝手に)使ったのが原因。
- ちなみに他にも色々候補となるものがある　　

> - Google公式(Class説明)
>> https://developer.android.com/reference/java/lang/ClassLoader 
 
> - classLoaderとは  
>> https://www.symmetric.co.jp/blog/archives/106  

#### 解決方法
`AndroirManifest.xml`の`application`タグ内に以下を追加

```xml
<uses-library android:name="org.apache.http.legacy"/>
```
- 参考  
https://developer.android.com/guide/topics/manifest/uses-library-element?hl=ja

--- 

### HTTP通信の無効化
http通信をしているところが、通信エラーになっていた。  
こんなエラーが出力される
```
java.io.IOException: Cleartext HTTP traffic (ドメイン)
```
端的に言うとATSみたいな対応が必要だった。

#### 原因
http通信してるものに対して接続許可する設定を行なっていなかった

#### 対処方法
1. `res/xml`に接続を許可するドメインを指定したxmlを配置する
2. `AndroidManifest.xml`の`application`タグで`android:networkSecurityConfig="@xml/1のxml名"`を設定する  

##### ドメイン指定のやり方

- 別々に指定する

```xml
<?xml version="1.0" encoding="utf-8"?>
<!-- http通信を許可するドメインリスト -->
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">接続許可するドメイン</domain>
    </domain-config>
</network-security-config>
```
- 一括指定する

```xml
<?xml version="1.0" encoding="utf-8"?>
<!-- http通信を許可するドメインリスト -->
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>
```

#### 参考記事  
- https://developer.android.com/training/articles/security-config?hl=ja#base-config  
- https://qiita.com/b_a_a_d_o/items/afa0d83bbffdb5d4f6be

---

### フォアグラウンドサービスのcrash
ローカル通知でcrash発生

```
Caused by: java.lang.SecurityException: Permission Denial: startForeground from pid=27952, uid=10244 requires android.permission.FOREGROUND_SERVICE
        at android.os.Parcel.createException(Parcel.java:1961)
        at android.os.Parcel.readException(Parcel.java:1927)
        at android.os.Parcel.readException(Parcel.java:1877)
        at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:5198)
        at android.app.Service.startForeground(Service.java:695)
```

#### 原因
パーミッションを指定しないで、`startForeground`していたのが原因

#### 解決方法

`AndroidManifest.xml`の`manifest`タブ内に以下のパーミッションの追加  

```xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
```

--- 

### crash対応
Googleさんが治してくれなかったので・・・(期待してたのに(´・ω・`))

#### 現象
`Activity`に対して、`themes`で`windowIsTranslucent`を`true`にしてる時、以下の条件でcrashする
- Android8.0
- 回転に関わるメソッドを呼び出す。`setRequestedOrientation`等(ただ、透明処理が悪いかも)
- `targetSDK`が`27`以上

#### 原因
わかりません。ちなみに`8.0`限定で`8.1`以降の端末は発生しない

#### 対処方法
- `windowIsTranslucent`を使用しない
- 透過が消えちゃうので、背景色に白でもいれる

## 以上となります。   
もっと色々調べれば粗がたくさん出そうだけど・・・調査した結果としてはこのあたりの問題がでました。