为了账号安全,请及时绑定邮箱和手机立即绑定

构建可在桌面和移动设备的任何地方运行的服务器

构建可在桌面和移动设备的任何地方运行的服务器

Go
万千封印 2022-09-26 15:07:29
我有以下简单的服务器,在我的笔记本电脑上运行(Mac / Windows / Linux):package mainimport (    "fmt"    "log"    "net/http")func handler(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "Hi there %s!", r.URL.Path[1:])}func main() {    http.HandleFunc("/", handler)    log.Println(http.ListenAndServe("localhost:6060", nil))}enter image description here我是否可以使用相同的代码库在移动设备上运行我的应用程序,而无需使用gomobile或其他软件包,以便将我的代码作为通用应用程序?webview
查看完整描述

1 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

答案是“是”,但需要对文件本身进行一些轻微的修改。

  1. 从 中删除所有内容,因为我们会将最终结果构建为共享库,而不是可执行二进制文件。func main() {}

  2. 在函数中运行服务器。//export

  3. 从 as 运行服务器,以便它不会阻塞移动应用程序的主线程。anonymous goroutinego func() {}()

  4. 为了保持服务器戈鲁丁的运行,我们需要使用一个通道来防止戈鲁廷退出。<-c

  5. 通过添加 来使用,因此主文件将如下所示:cgoimport "C"

package main


import "C"


// other imports should be seperated from the special Cgo import

import (

    "fmt"

    "log"

    "net/http"

)


//export server

func server() {

    c := make(chan bool)

    go func() {

        log.Println(http.ListenAndServe("localhost:6060", nil))

        <-c

    }()


    http.HandleFunc("/", handler)


}


func handler(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "Hi there %s!", r.URL.Path[1:])

}


func main() {}

确保安装了安卓系统,并且您知道它的浴缸NDK

生成输出名称为 的输出,以生成以供使用:c-sharedlibxxxAndroid

    CGO_ENABLED=1 \

    GOOS=android \

    GOARCH=arm \

    GOARM=7 \

    CC=$(NDK_BIN)/armv7a-linux-androideabi21-clang \

    go build -buildmode=c-shared -o libfoo.so http.go

等由于Android具有多个架构,我们需要单独编译每个架构,因此我们可以在创建Android应用程序后,通过从项目模板中进行选择,在输出库名称下方,所有过程都可以自动执行,并且每个文件夹中将生成2个文件,并且:MakefileNative C++libfoolibfoo.solibfoo.h


enter image description here


#Filename: Makefile

# To compile run:

# make android


IOS_OUT=lib/ios

ANDROID_OUT=../android_app/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

转到并执行以下操作:8.1。文件 ,将其设置为:android_app/app/src/main/cppCMakeLists.txt

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} )

8.2. 文件设置为:native-lib.cpp


#include <jni.h>

#include <string>


#include "libfoo.h" // our library header


extern "C" {

    void

    Java_tk_android_MainActivity_serverJNI() {

        // Running the server

        server();

    }

}

将网页视图添加到 中,如下所示:layout/activity_main

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity">


    <WebView

        android:id="@+id/wv"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:isScrollContainer="false"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintHorizontal_bias="0.0"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

更新如下:MainActivity

package tk.android


import android.os.Bundle

import android.webkit.WebView

import android.webkit.WebViewClient

import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)


        var wv = findViewById<WebView>(R.id.web_view)

        serverJNI()

        wv.loadUrl("http://127.0.0.1:6060/")

        wv.webViewClient = object : WebViewClient() {

            override fun shouldOverrideUrlLoading(viewx: WebView, urlx: String): Boolean {

                viewx.loadUrl(urlx)

                return false

            }

        }

    }


    private external fun serverJNI(): Void


    companion object {

        // Used to load the 'native-lib' library on application startup.

        init {

            System.loadLibrary("native-lib")

        }

    }

}

更新为:AndroidManifest

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="tk.android">


    <!-- Mandatory:

                android:usesCleartextTraffic="true"

         Optional: 

                android:hardwareAccelerated="true" 

         Depending on the action bar required:

                android:theme="@style/Theme.AppCompat.NoActionBar"

    -->

    <application

        android:hardwareAccelerated="true"     // <- Optional 

        android:usesCleartextTraffic="true"     // <- A must to be added

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:roundIcon="@mipmap/ic_launcher_round"

        android:supportsRtl="true"

        android:theme="@style/Theme.AppCompat.NoActionBar">   // <- If do not want action bar

        <activity android:name=".MainActivity"

            android:configChanges="orientation|screenSize">   // <- A must to avoid crashing at rotation

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>


</manifest>

enter image description hereenter image description here

奖金使用 Go,所有静态文件都可以嵌入到同一库中,包括 、,因此您可以使用 GUI 构建 API 或完整的应用程序embedcssjavascripttemplates

enter image description here


查看完整回答
反对 回复 2022-09-26
  • 1 回答
  • 0 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信