#android
Вопрос:
Пытаюсь запустить локальный сервер из приложения для Android, но приложение продолжает уничтожать время нажатия кнопки для запуска сервера, мой код:
package tk.android
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Example of a call to a native method
findViewById<TextView>(R.id.sample_text).text = stringFromJNI()
btn.setOnClickListener {
txt.setText(reverse(txt.text.toString()))
server()
}
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
external fun stringFromJNI(): String
external fun server() : Void // extern void server(); // Here is the server
private external fun reverse(str: String): String // extern char* reverse(char* in)
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
}
Приложение для Android построено с использованием собственных функций, в которых определены 3 функции, 2 из которых затем работают бесперебойно, но та, которая связана с сервером, сбоит.
Мои собственные функции определяются как:
// file cpp/native-lib.cpp
#include <jni.h>
#include <string>
#include "libfoo.h" // our library header
extern "C" JNIEXPORT jstring JNICALL
Java_tk_android_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C ";
return env->NewStringUTF(hello.c_str());
}
extern "C" {
jstring
Java_tk_android_MainActivity_reverse(JNIEnv* env, jobject, jstring str) {
// Reverse text here
const char* cstr = env->GetStringUTFChars(str, 0);
char* cout = reverse(const_cast<char*>(cstr));
jstring out = env->NewStringUTF(cout);
env->ReleaseStringUTFChars(str, cstr);
free(cout);
return out;
}
}
extern "C" {
void
Java_tk_android_MainActivity_server() {
// Nothing here, as it is void input and void output
server();
}
}
With the CMake file defined as:
cmake_minimum_required(VERSION 3.10.2)
project("android")
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp )
add_library(lib_foo SHARED IMPORTED)
set_property(TARGET lib_foo PROPERTY IMPORTED_NO_SONAME 1)
set_target_properties(lib_foo PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libfoo.so)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
lib_foo
# Links the target library to the log library
# included in the NDK.
${log-lib} )
The server file I’m running is simple one built with GO, and compiled as shared library
package main
import "C"
// other imports should be seperate from the special Cgo import
import (
"fmt"
"log"
"net/http"
)
//export reverse
func reverse(in *C.char) *C.char {
return C.CString(foo.Reverse(C.GoString(in)))
}
//export server
func server() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func Reverse(in string) string {
n := 0
rune := make([]rune, len(in))
for _, r := range in {
rune[n] = r
n
}
rune = rune[0:n]
for i := 0; i < n/2; i {
rune[i], rune[n-1-i] = rune[n-1-i], rune[i]
}
return string(rune)
}
func main() {}
Compiled to Android with the below Make file:
//file: Makefile
ANDROID_OUT=../myApp/app/src/main/jniLibs
ANDROID_SDK=$(HOME)/Library/Android/sdk
NDK_BIN=$(ANDROID_SDK)/ndk/23.0.7599858/toolchains/llvm/prebuilt/darwin-x86_64/bin
android-armv7a:
CGO_ENABLED=1
GOOS=android
GOARCH=arm
GOARM=7
CC=$(NDK_BIN)/armv7a-linux-androideabi21-clang
go build -buildmode=c-shared -o $(ANDROID_OUT)/armeabi-v7a/libfoo.so ./cmd/libfoo
android-arm64:
CGO_ENABLED=1
GOOS=android
GOARCH=arm64
CC=$(NDK_BIN)/aarch64-linux-android21-clang
go build -buildmode=c-shared -o $(ANDROID_OUT)/arm64-v8a/libfoo.so ./cmd/libfoo
android-x86:
CGO_ENABLED=1
GOOS=android
GOARCH=386
CC=$(NDK_BIN)/i686-linux-android21-clang
go build -buildmode=c-shared -o $(ANDROID_OUT)/x86/libfoo.so ./cmd/libfoo
android-x86_64:
CGO_ENABLED=1
GOOS=android
GOARCH=amd64
CC=$(NDK_BIN)/x86_64-linux-android21-clang
go build -buildmode=c-shared -o $(ANDROID_OUT)/x86_64/libfoo.so ./cmd/libfoo
android: android-armv7a android-arm64 android-x86 android-x86_64
Я не знаю, есть ли что-то неправильное в определении Java_tk_android_MainActivity_server()
или это сбой, потому что сервер будет прослушивать http-сигнал!
Я получил следующее только после сбоя приложения:
Я/болтливый: uid=10104(tk.android) Поток-2 идентичных 1 строка Без tk.android: Доступ к скрытому методу Landroid/база данных/sqlite/база данных SQLiteDatabase;->yieldIfContendedHelper(ZJ)Z (серый список-макс.o, ссылка, отказано)
Комментарии:
1. Пожалуйста, отредактируйте свой вопрос, чтобы включить трассировку стека
2. @Код-Ученик, которого я получил
I/chatty: uid=10104(tk.android) Thread-2 identical 1 line W/tk.android: Accessing hidden method Landroid/database/sqlite/SQLiteDatabase;->yieldIfContendedHelper(ZJ)Z (greylist-max-o, linking, denied)
3.
I
это «информация». ИW
является «предупреждением». Ни то, ни другое не является ошибкой. Вам нужно будет копнуть глубже в logcat, чтобы найти ошибку в результате сбоя.