Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个Ability),OpenHarmony OS支持应用以Ability为单位进行部署。Ability可以分为FA(Feature Ability)和PA(Particle Ability)两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。以上摘自官方文档,本文简要介绍Page应用(AceAbility为例)启动过程 ,减少入手难度。aa start -a <ability-name> -b <bundle-name>
e.g. aa start -a com.example.myapplication.MainAbility -b com.example.myapplication
//startup/appspawn/standard/appspawn_service.c
appspawn_service.c 调用OnReceiveRequest()处理请求,fork子进程 *childPid = AppSpawnFork(AppSpawnChild, (void *)sandbox);//base/startup/appspawn/common/appspawn_server.c
*childPid = AppSpawnFork(AppSpawnChild, (void *)sandbox);
AppSpawnChild中执行应用启动前步骤,如清理环境、权限鉴权等后,调用content->runChildProcessor(content, client)。//startup/appspawn/adapter/appspawn_ace.cpp
在Start()中装备应用MainThread的EventRunner和MainHandler,在EventRunner::Run等待event分发处理和event循环,这里是应用的主线程,也负责拉起其他的线程。这里有必要简要说明OHOS的事件通知机制。
OHOS event-notification机制可以保证一个线程中可以安全地向其他线程投递任务,只要拿到其他线程的Handler或者EventRunner即可。UML类图:
说明:(1). EventHandler负责投递封装好的event到EventRunner的EventQueue中,并提供ProcessEvent接口供子类重写业务逻辑。(2). EventRunner负责线程运行的抽象,实际线程运行委托给EventInnerRunner实现。(3). EventInnerRunner/EventRunnerImpl类是线程运行具体实现,提供ThreadMain()作为std::thread运行入口,在Run()完成event分发处理和event循环(EventHanlder在投递event时候,将handler本身封装在event中,之所以这样做,可能是为了同时支持callback型task和EventHandler中重写ProcessEvent处理方式)。
拉起看DFX的看门狗线程和信号处理线程,设置应用主线程状态。
MainThread是IRemoteStub<IAppScheduler>子类,向AMS注册反向死亡通知,应用退出能及时释放AMS相关资源。获取AppMgr Proxy对象 AttachApplication之后,AMS调度Application状态。
说明:MainThread、AMS、ABMS运行在不同进程中,其中AMS、ABMS是SA,使用ohos IPC机制通信。1.MainThread 是IRemoteStub<IAppScheduler> 子类,是一个匿名IPC对象(匿名这里指的是没有注册到samgr,无said),反向死亡通知到AMS,应用结束时候可以通知AMS回收已分配的AppRunningRecord资源。2.AppThread(应用主线程,即MainThread)向AMS发送APP_ATTACH_APPLICATION请求并置MainThread状态为Attach,AMS侧收到请求创建appRecord,标记APP_STATE_CREATE。3.AMS判断appRecord 为ApplicationState::APP_STATE_CREATE,向Application发送SCHEDULE_LAUNCH_APPLICATION_TRANSACTION请求。4.AMS标记appRecord状态为APP_STATE_READY。5.AppThread接收到AMS的SCHEDULE_LAUNCH_APPLICATION_TRANSACTION请求后,调用ScheduleLaunchApplication向MainThread投递任务。void MainThread::ScheduleLaunchApplication(const AppLaunchData &data, const Configuration &config)
{
......
wptr<MainThread> weak = this;
auto task = [weak, data, config]()
{
auto appThread = weak.promote();
if (appThread == nullptr)
{
HILOG_ERROR("appThread is nullptr, HandleLaunchApplication failed.");
return;
}
appThread->HandleLaunchApplication(data, config);
};
if (!mainHandler_->PostTask(task))
......
}if (info && info->type == AbilityType::PAGE) {
ability_->SetSceneListener(
sptr<WindowLifeCycleImpl>(new WindowLifeCycleImpl(token_, shared_from_this())));
}void AbilityThread::Attach(std::shared_ptr<OHOSApplication> &application,
const std::shared_ptr<AbilityLocalRecord> &abilityRecord, const std::shared_ptr<EventRunner> &mainRunner,
const std::shared_ptr<AbilityRuntime::Context> &stageContext)
{
// 1.new AbilityHandler 根据不同AbilityType获得abilityName
std::string abilityName = CreateAbilityName(abilityRecord, application);
if (abilityName == "") {
HILOG_ERROR("Attach ability failed, abilityInfo is nullptr.");
return;
}
HILOG_DEBUG("Attach ability begin, ability:%{public}s.", abilityRecord->GetAbilityInfo()->name.c_str());
abilityHandler_ = std::make_shared<AbilityHandler>(mainRunner);
if (abilityHandler_ == nullptr) {
HILOG_ERROR("Attach ability failed, abilityHandler_ is nullptr.");
return;
}
// 2.new ability 创建不同的ability,这里以AceAbility为例
auto ability = AbilityLoader::GetInstance().GetAbilityByName(abilityName);
if (ability == nullptr) {
HILOG_ERROR("Attach ability failed, load ability failed.");
return;
}
......
// 3.new abilityImpl
abilityImpl_ =
DelayedSingleton<AbilityImplFactory>::GetInstance()->MakeAbilityImplObject(abilityRecord->GetAbilityInfo());
if (abilityImpl_ == nullptr) {
HILOG_ERROR("Attach ability failed, abilityImpl_ == nullptr.");
return;
}
// 这里初始化abilityWindow及AbilityLifeCycle
abilityImpl_->Init(application, abilityRecord, currentAbility_, abilityHandler_, token_, contextDeal);
// 4. ability attach : ipc
ErrCode err = AbilityManagerClient::GetInstance()->AttachAbilityThread(this, token_);
if (err != ERR_OK) {
HILOG_ERROR("Attach ability failed, err = %{public}d.", err);
return;
}if (((curState_ == APP_STATE_READY) || (curState_ == APP_STATE_BACKGROUND)) && application_ != nullptr) {
application_->OnForeground();
curState_ = APP_STATE_FOREGROUND;
return true;
}最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject
是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T
我想覆盖store_accessor的getter。可以查到here.代码在这里:#Fileactiverecord/lib/active_record/store.rb,line74defstore_accessor(store_attribute,*keys)keys=keys.flatten_store_accessors_module.module_evaldokeys.eachdo|key|define_method("#{key}=")do|value|write_store_attribute(store_attribute,key,value)enddefine_met
我想用Capistrano启动sidekiq。下面是代码namespace:sidekiqdotask:startdorun"cd#{current_path}&&bundleexecsidekiq-c10-eproduction-Llog/sidekiq.log&"pcapture("psaux|grepsidekiq|awk'{print$2}'|sed-n1p").strip!endend它执行成功但sidekiq仍然没有在服务器上启动。输出:$capsidekiq:starttriggeringloadcallbacks*2014-06-0315:03:01executing`
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
我已经开始学习Ruby,我已经阅读了一些教程,甚至还买了一本书(“ProgrammingRuby1.9-ThePragmaticProgrammers'Guide”),我遇到了一些以前从未见过的新东西使用我知道的任何其他语言(我是一名PHP网络开发人员)。block和过程。我想我明白它们是什么,但我不明白的是为什么它们如此伟大,以及我应该在何时何地使用它们。我到处都看到他们说block和过程是Ruby中的一个很棒的特性,但我不理解它们。这里有人能给像我这样的Ruby新手一些解释吗? 最佳答案 block有很多好处。电梯演讲:bloc
我有一个正在升级到Rails3的Rails2.3.5应用程序。我做了所有我需要做的升级以及当我使用启动Rails服务器时要做的事情railsserver它给了我这个PleaseswitchtoRuby1.9'sstandardCSVlibrary.It'sFasterCSVplussupportforRuby1.9'sm17nencodingengine.我正在使用ruby-1.9.2-p0并安装了fastercsv(1.5.3)gem。在puts语句的帮助下,我能够追踪到错误发生的位置。我发现执行在这一行停止了Bundler.require(:default,Rails.env)if
电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑