7android怎么了?

What's wrong with 7 android?

我有接收 udp 数据报套接字的服务

     private void startServer(final UdpServerListener listener) {

     mStarted = true;
            mWakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
            Looper myLooper = Looper.myLooper();

            new HandlerThread("TcpServerThread") {
                @Override
                protected void onLooperPrepared() {
                    new Handler(getLooper()).post(() -> {
                        try {
                            byte[] data = new byte[8 * 1024];

                            InetAddress address = BnjUtils.getLocalIpAddress();

                            DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
                            mServerSocket = new DatagramSocket(0, address);

                            final InetAddress localAddress = ((InetSocketAddress) mServerSocket.getLocalSocketAddress()).getAddress();
                            final int port = mServerSocket.getLocalPort();


                            while (mStarted) {

                                try {

                                   mServerSocket.receive(datagramPacket); // blocks until something is received
                                    /*
                                     * Send bytes to app module.
                                     */
                                    byte[] receiveData = new byte[datagramPacket.getLength()];

                                    System.arraycopy(datagramPacket.getData(), datagramPacket.getOffset(), receiveData, 0, datagramPacket.getLength());

     //POST MY DATA TO BINDER VIA HANDLE LOOPER AND LISTENER                                       
    new Handler(myLooper).post(() -> listener.onReceive(receiveData,datagramPacket.getAddress()));


                                } catch (IOException e) {
                                    new Handler(myLooper).post(() -> listener.onServerStartFailed(e));
                                }
                            }
                        } catch (SocketException e) {
                            Log.e(mTag, "Socket Exception");
                        } finally {
                            if (mServerSocket != null && !mServerSocket.isClosed()) {
                                mServerSocket.close();
                            }
                            getLooper().quitSafely();
                        }
                    });
                }
            }.start();
        }

因此结果数据 i post 通过 Binder

发送给监听器
  //POST MY DATA TO BINDER VIA HANDLE LOOPER AND LISTENER       
 new Handler(myLooper).post(() -> listener.onReceive(receiveData,datagramPacket.getAddress()));

看看我的听众:

@NonNull
private UdpServerService.UdpServerListener getUdpServerServiceListener() {

    if (mUdpServerServiceListener == null) {
        mUdpServerServiceListener = new UdpServerService.UdpServerListener() {

            @Override
            public void onReceive(final byte[] bytes, final InetAddress inetAddress) {
                if (mSocketListener != null && mListenerLooper != null) {

                    //TRY TO RECEIVW MY DATA HERE
                }
            }

        };
    }
    return mUdpServerServiceListener;
}

查看我的服务连接 class 与活页夹

private class MyServiceConnection implements ServiceConnection {

        UdpServerService.UdpServerBinder binder;

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (service instanceof UdpServerService.UdpServerBinder && mServerState == SERVER_STARTED) {
                binder = (UdpServerService.UdpServerBinder) service;
                binder.setListener(getUdpServerServiceListener());
                binder.startServer();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //do something on disconnect
        }

所以,这一切都很好,但在版本 5 和 6 的旧设备中 Android。

但在我的 GalaxyS7 或我的 Asus Zenfone 3 中

with Android 7 application freezes

并且在未停止之前不会响应用户触摸。

可能触发了一些限制机制,但我对此一无所知。

可能是错误的build.gradle 看到了

    apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

apply plugin: 'idea'

android {
    compileSdkVersion 26

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        useLibrary 'org.apache.http.legacy'
    }

    buildTypes {

        debug {
            minifyEnabled false
            debuggable true
            signingConfig signingConfigs.debug
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        release {
            minifyEnabled true
            debuggable false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }

    }
    packagingOptions{
        exclude 'META-INF/rxjava.properties'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    //gson parser
    implementation 'com.google.code.gson:gson:2.8.0'
    //kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

    // rxjava
    implementation  'io.reactivex:rxjava:1.1.6'
    implementation  'io.reactivex:rxandroid:1.2.1'
    implementation  'com.artemzin.rxjava:proguard-rules:1.1.0.0'

    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'io.reactivex.rxjava2:rxjava:2.0.8'

    //help to avoid  memory leaks
    implementation 'com.badoo.mobile:android-weak-handler:1.0'

    //guava for Android:
    implementation 'com.google.guava:guava:23.6-android'

}

kotlin {
    experimental {
        coroutines "enable"
    }
}

我的解决方案是简化这段代码,只需要在简单的线程中接收数据,post它的数据在同一个线程中:

 void startServer() {
            mStarted = true;
            mWakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);

            new Thread(() -> {
                try {
                    byte[] data = new byte[8 * 1024];//bucketful with fix size
                    InetAddress address = BnjUtils.getLocalIpAddress();

                    DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
                    mServerSocket = new DatagramSocket(0, address);

                    final InetAddress localAddress = ((InetSocketAddress) mServerSocket.getLocalSocketAddress()).getAddress();
                    final int port = mServerSocket.getLocalPort();
                    mListener.onServerCreated(localAddress, port);

                    while (mStarted) {
                        try {

                            mServerSocket.receive(datagramPacket); // blocks until something is received
                            /*
                             * Send bytes to app module.
                             */
                            byte[] receiveData = new byte[datagramPacket.getLength()];

                            System.arraycopy(datagramPacket.getData(), datagramPacket.getOffset(), receiveData, 0, datagramPacket.getLength());
                            mListener.onReceive(receiveData, datagramPacket.getAddress());

                        } catch (IOException e) {
                            mListener.onServerStartFailed(e);
                        }
                    }
                } catch (SocketException e) {
                    Log.e(mTag, "Socket Exception");
                } finally {
                    if (mServerSocket != null && !mServerSocket.isClosed()) {
                        mServerSocket.close();
                    }
                }
            }).start();
        }

所以现在,工作没有冻结。