Hippy项目源码分析(五)

本文介绍了如何在Android应用中集成JavaScript的TimerModule,演示了如何设置和清除定时器,以及如何通过JSCVM和JSCCtx进行跨平台交互。实例展示了如何创建定时器,设置守护线程,并展示了与Android UI的简单交互,如自定义弹出框操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021SC@SDUSC

首篇文章已说明我的分工:Core全部内容

目录

include\core\modules\timer_module.h

include\core\napi\jcs\js_native_api-jsc.h

include\core\modules\timer_module.h

#pragma once

#include <memory>
#include <unordered_map>
#include <utility>

#include "core/base/task.h"
#include "core/modules/module_base.h"
#include "core/napi/callback_info.h"
#include "core/napi/js_native_api.h"
#include "core/napi/js_native_api_types.h"

class JavaScriptTask;
class JavaScriptTaskRunner;

class TimerModule : public ModuleBase {
 public:
  TimerModule();
  ~TimerModule();

  void SetTimeout(const hippy::napi::CallbackInfo& info);
  void ClearTimeout(const hippy::napi::CallbackInfo& info);
  void SetInterval(const hippy::napi::CallbackInfo& info);
  void ClearInterval(const hippy::napi::CallbackInfo& info);

 private:
  using TaskId = hippy::base::Task::TaskId;
  using CtxValue = hippy::napi::CtxValue;
  using Ctx = hippy::napi::Ctx;

  std::shared_ptr<CtxValue> Start(const hippy::napi::CallbackInfo& info,
                                  bool repeat);
  void RemoveTask(const std::shared_ptr<JavaScriptTask>& task);
  void Cancel(TaskId task_id, const std::shared_ptr<Scope>& scope);

  struct TaskEntry {
    TaskEntry(std::shared_ptr<CtxValue> func,
              std::weak_ptr<JavaScriptTask> task): func(func), task(task) {}

    std::shared_ptr<CtxValue> func;
    std::weak_ptr<JavaScriptTask> task;
  };

  std::unordered_map<TaskId, std::shared_ptr<TaskEntry>> task_map_;

  static const int kTimerInvalidId = 0;
};

    timer总结:
    Timer timer = new Timer();    //其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字
    Timer timer = new Timer(String name);    //以name作为该定时器的名字
    Timer timer = new Timer(boolean isDeamon);    //是否将此定时器作为守护线程执行
    Timer timer = new Timer(name, isDeamon);    //定时器名字, 是否为守护线程
 

include\core\napi\jcs\js_native_api-jsc.h

#pragma once

#include <JavaScriptCore/JavaScriptCore.h>
#include <stdio.h>

#include <mutex>
#include <vector>

#include "base/logging.h"
#include "base/unicode_string_view.h"
#include "core/base/macros.h"
#include "core/napi/js_native_api_types.h"

template <std::size_t N>
constexpr JSStringRef CreateWithCharacters(const char16_t (&u16)[N]) noexcept {
  return JSStringCreateWithCharacters((const JSChar*)u16, N - 1);
}

namespace hippy {
namespace napi {

const char16_t kLengthStr[] = u"length";
const char16_t kMessageStr[] = u"message";
const char16_t kStackStr[] = u"stack";

class JSCVM : public VM {
 public:
  JSCVM(): VM(nullptr) { vm_ = JSContextGroupCreate(); }

  ~JSCVM() {
    JSContextGroupRelease(vm_);
    vm_ = nullptr;
  }
  JSContextGroupRef vm_;

  virtual void RegisterUncaughtExceptionCallback();
  virtual std::shared_ptr<Ctx> CreateContext();
};

class JSCCtxValue;

class JSCCtx : public Ctx {
 public:
  using unicode_string_view = tdf::base::unicode_string_view;
  using JSValueWrapper = hippy::base::JSValueWrapper;

  explicit JSCCtx(JSContextGroupRef vm) {
    context_ = JSGlobalContextCreateInGroup(vm, nullptr);

    exception_ = nullptr;
    is_exception_handled_ = false;
  }

  ~JSCCtx() {
    exception_ = nullptr;

    JSGlobalContextRelease(context_);
    context_ = nullptr;
  }

  JSGlobalContextRef GetCtxRef() { return context_; }

  inline std::shared_ptr<JSCCtxValue> GetException() { return exception_; }
  inline void SetException(std::shared_ptr<JSCCtxValue> exception) {
    if (is_exception_handled_) {
      return;
    }
    exception_ = exception;
    if (exception) {
      is_exception_handled_ = false;
    }
  }
  inline bool IsExceptionHandled() { return is_exception_handled_; }
  inline void SetExceptionHandled(bool is_exception_handled) {
    is_exception_handled_ = is_exception_handled;
  }
  virtual bool RegisterGlobalInJs() override;
  virtual bool SetGlobalJsonVar(const unicode_string_view& name,
                                const unicode_string_view& json) override;
  virtual bool SetGlobalStrVar(const unicode_string_view& name,
                               const unicode_string_view& str) override;
  virtual bool SetGlobalObjVar(const unicode_string_view& name,
                               const std::shared_ptr<CtxValue>& obj,
                               const PropertyAttribute& attr = None) override;
  virtual std::shared_ptr<CtxValue> GetGlobalStrVar(
      const unicode_string_view& name) override;
  virtual std::shared_ptr<CtxValue> GetGlobalObjVar(
      const unicode_string_view& name) override;
  virtual std::shared_ptr<CtxValue> GetProperty(
      const std::shared_ptr<CtxValue>& object,
      const unicode_string_view& name) override;

  virtual void RegisterGlobalModule(const std::shared_ptr<Scope>& scope,
                                    const ModuleClassMap& modules) override;
  virtual void RegisterNativeBinding(const unicode_string_view& name,
                                     hippy::base::RegisterFunction fn,
                                     void* data) override;

  virtual std::shared_ptr<CtxValue> CreateNumber(double number) override;
  virtual std::shared_ptr<CtxValue> CreateBoolean(bool b) override;
  virtual std::shared_ptr<CtxValue> CreateString(
      const unicode_string_view& string) override;
  virtual std::shared_ptr<CtxValue> CreateUndefined() override;
  virtual std::shared_ptr<CtxValue> CreateNull() override;
  virtual std::shared_ptr<CtxValue> CreateObject(
      const unicode_string_view& json) override;
  virtual std::shared_ptr<CtxValue> CreateMap(size_t count,
                                              std::shared_ptr<CtxValue>* value) override {
      TDF_BASE_NOTIMPLEMENTED();
      return nullptr;
  };
  virtual std::shared_ptr<CtxValue> CreateArray(
      size_t count,
      std::shared_ptr<CtxValue> value[]) override;
  virtual std::shared_ptr<CtxValue> CreateJsError(
      const unicode_string_view& msg) override;

  // Get From Value
  virtual std::shared_ptr<CtxValue> CallFunction(
      const std::shared_ptr<CtxValue>& function,
      size_t argument_count = 0,
      const std::shared_ptr<CtxValue> argumets[] = nullptr) override;

  virtual bool GetValueNumber(const std::shared_ptr<CtxValue>& value, double* result) override;
  virtual bool GetValueNumber(const std::shared_ptr<CtxValue>& value, int32_t* result) override;
  virtual bool GetValueBoolean(const std::shared_ptr<CtxValue>& value, bool* result) override;
  virtual bool GetValueString(const std::shared_ptr<CtxValue>& value,
                              unicode_string_view* result) override;
  virtual bool GetValueJson(const std::shared_ptr<CtxValue>& value,
                            unicode_string_view* result) override;
  virtual bool IsMap(const std::shared_ptr<CtxValue>& value) override {
      TDF_BASE_NOTIMPLEMENTED();
      return false;
  };
  // Null Helpers
  virtual bool IsNullOrUndefined(const std::shared_ptr<CtxValue>& value) override;

  // Array Helpers

  virtual bool IsArray(const std::shared_ptr<CtxValue>& value) override;
  virtual uint32_t GetArrayLength(const std::shared_ptr<CtxValue>& value) override;
  virtual std::shared_ptr<CtxValue> CopyArrayElement(const std::shared_ptr<CtxValue>& value, uint32_t index) override;

  // Object Helpers

  virtual bool HasNamedProperty(const std::shared_ptr<CtxValue>& value,
                                const unicode_string_view& name) override;
  virtual std::shared_ptr<CtxValue> CopyNamedProperty(
      const std::shared_ptr<CtxValue>& value,
      const unicode_string_view& name) override;
  // Function Helpers

  virtual bool IsFunction(const std::shared_ptr<CtxValue>& value) override;
  virtual unicode_string_view CopyFunctionName(const std::shared_ptr<CtxValue>& value) override;

  virtual std::shared_ptr<CtxValue> RunScript(
      const unicode_string_view& data,
      const unicode_string_view& file_name,
      bool is_use_code_cache = false,
      unicode_string_view* cache = nullptr,
      bool is_copy = true) override;
  virtual std::shared_ptr<CtxValue> GetJsFn(const unicode_string_view& name) override;
  virtual bool ThrowExceptionToJS(const std::shared_ptr<CtxValue>& exception) override;

  virtual std::shared_ptr<JSValueWrapper> ToJsValueWrapper(
      const std::shared_ptr<CtxValue>& value) override;
  virtual std::shared_ptr<CtxValue> CreateCtxValue(
      const std::shared_ptr<JSValueWrapper>& wrapper) override;

  unicode_string_view GetExceptionMsg(const std::shared_ptr<CtxValue>& exception);
  JSStringRef CreateJSCString(const unicode_string_view& str_view);

  JSGlobalContextRef context_;
  std::shared_ptr<JSCCtxValue> exception_;
  bool is_exception_handled_;
};

inline tdf::base::unicode_string_view ToStrView(JSStringRef str) {
  return tdf::base::unicode_string_view(
      reinterpret_cast<const char16_t*>(JSStringGetCharactersPtr(str)),
      JSStringGetLength(str));
}

class JSCCtxValue : public CtxValue {
 public:
  JSCCtxValue(JSGlobalContextRef context, JSValueRef value)
      : context_(context), value_(value) {
    JSValueProtect(context_, value_);
  }

  ~JSCCtxValue() { JSValueUnprotect(context_, value_); }

  JSGlobalContextRef context_;
  JSValueRef value_;

  DISALLOW_COPY_AND_ASSIGN(JSCCtxValue);
};

class JSCTryCatch : public TryCatch {
 public:
  JSCTryCatch(bool enable, std::shared_ptr<Ctx> ctx);
  virtual ~JSCTryCatch();
  virtual void ReThrow();
  virtual bool HasCaught();
  virtual bool CanContinue();
  virtual bool HasTerminated();
  virtual bool IsVerbose();
  virtual void SetVerbose(bool verbose);
  virtual std::shared_ptr<CtxValue> Exception();
  virtual tdf::base::unicode_string_view GetExceptionMsg();

 private:
  std::shared_ptr<JSCCtxValue> exception_;
  bool is_verbose_;
  bool is_rethrow_;
};

}  // namespace napi
}  // namespace hippy

android Java程序

import android.app.AlertDialog;
 //...
 // 创建提示框构造对象,Builder是AlertDialog的内部类。参数this指代Android的主Activity对象,该对象启动应用时自动生成
 AlertDialog.Builder dlg = new AlertDialog.Builder(this);
 // 设置提示框标题
 dlg.setTitle("自定义标题");
 // 设置提示框内容
 dlg.setMessage("使用NJS的原生弹出框,可自定义弹出框的标题、按钮");
 // 设置提示框按钮
 dlg.setPositiveButton("确定(或者其他字符)", null);
 // 显示提示框
 dlg.show();
 //...
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值