前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >「Learn」开发记录

「Learn」开发记录

作者头像
AnRFDev
发布于 2021-02-01 07:19:33
发布于 2021-02-01 07:19:33
1.3K00
代码可运行
举报
文章被收录于专栏:AnRFDevAnRFDev
运行总次数:0
代码可运行

开发App过程中遇到的一些问题和解决办法。临时记录一些解决方案。

音频

Android MediaPlayer基础。

在线音频播放,使用MediaPlayer。

下载在线音频到本地,使用URLConnection。

自定义ViewGroup

继承自LinearLayout,自定义子View的排布方式。

crash ViewGroup.resetResolvedLayoutDirection

给LinearLayout addView的时候报错

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
E/AndroidRuntime:     at android.view.ViewGroup.resetResolvedLayoutDirection(ViewGroup.java:7291)
    at android.view.ViewGroup.resetResolvedLayoutDirection(ViewGroup.java:7291)

检查代码,发现addView的时候把LinearLayout自己添加进去了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final LinearLayout wordCube = new LinearLayout(this);
wordCube.addView(wordCube, chTvParams);

改成

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final LinearLayout wordCube = new LinearLayout(this);
wordCube.addView(tv, chTvParams); // 要加的是tv

Bugly热更新

Bugly热更新方案集成了腾讯的tinker,自带了补丁包发布平台。

文档

https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20181014122344#_3

tinker不支持热更新新增四大组件,不能修改Manifest文件。但是可以修改四大组件里面的逻辑。

可以修改layout文件和资源文件。

Assets遍历文件

assets里存放着四千多个文件,红米6A遍历一次要2秒多。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String[] list = context.getAssets().list("folder"); // 执行这一句要两千多毫秒

语音识别方案

主力方案为百度语音识别

综合价格考虑,将科大讯飞的语音听写作为备用方案。

将百度语音识别与讯飞听写的SDK一起引入到App中。由后台控制用户使用哪一个语音引擎。

下载文件

项目采用的是mvvm架构。有2个页面要用到同一个数据源。把这个数据源单独抽出来,设计监听器。

原框架的下载文件功能有一个bug。如果下载时抛出了异常,也会调用success回调。

这里是在下载时记录目标文件的长度,在success回调中检查本地文件大小与这个长度是否一致。

限速下载

在io流那里进行延时操作。用Thread.sleep方法。

阻塞的是socket的操作。

下载安装apk

下载了新版本apk后,调用代码进行安装。根据手机系统版本的不同选择不同的安装方式。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static  void installApk(Context context,String downloadApk) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    File file = new File(downloadApk);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Uri apkUri = FileProvider.getUriForFile(context, "com.iNTGO.nndc.fileprovider", file);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    } else {
        Uri uri = Uri.fromFile(file);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
    }
    context.startActivity(intent);
}

对于小米4c android 5.1.1(API 22),如果把apk放在app内部存储,packageInstaller是无法安装的。要把apk放在公共存储中才能安装。

修改Android系统镜像(img)

装一个VMware Workstation Pro,下载一个Ubuntu 16的镜像(iso)。用的是阿里云的资源,比较快。

一系列的mount,打包后,刷机一直不成功。找到个ROM助手,尝试一下。修改了system.img后,线刷进去,卡米(卡在开机的MI logo界面)。

查一下发现,是selinux处于enforcing状态,没法装。小米4c用的是MIUI8,商家说没法root。MiUI7可以root。

还没找到非root情况下关闭selinux的方法。

动画效果

加一些动效会让界面更加生动有活力。

属性动画 - 星星飞行

控制星星飞入,定位,飞出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        final int flyInTime = 100;
        final int stayTime = 520;
        final int flyOutTime = 250;
        final int totalTime = flyInTime + stayTime + flyOutTime;
        binding.starIv.setX(inX);
        binding.starIv.setY(yStay);
        binding.starIv.setVisibility(View.VISIBLE);
        setStarIvSize(0, 0);
        final ValueAnimator animator = ValueAnimator.ofInt(1, totalTime);
        animator.setDuration(totalTime);
        animator.setInterpolator(new AccelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int value = (int) valueAnimator.getAnimatedValue();
                ImageView starIv = binding.starIv;
                if (value < flyInTime) {
                    float inProgress = value / (1.0f * flyInTime);
                    float x = inProgress * (xStay - inX) + inX;
                    float y;
                    if (value < flyInTime / 2) {
                        y = yStay + 20 - inProgress * 60;
                    } else {
                        y = yStay - 20 + inProgress * 60;
                    }
                    starIv.setX(x);
                    starIv.setY(y);
                    setStarIvSize((int) (mStarIvOriginWid * (inProgress)), (int) (mStarIvOriginHeight * (inProgress)));
//                    Log.d(TAG, "onAnimationUpdate: value: " + value + ", progress: " + inProgress + ", x: " + x);
                } else if (value < flyInTime + stayTime) {
                    starIv.setX(xStay);
                    starIv.setY(yStay);
                    setStarIvSize(mStarIvOriginWid, mStarIvOriginHeight);
                } else {
                    if (valueAnimator.isRunning()) {
                        float progress = (value - flyInTime - stayTime) / (1.0f * flyOutTime);
                        starIv.setX(xStay + (progress * Math.abs(endX - xStay)));
                        starIv.setY(yStay - (progress * Math.abs(endY - yStay)));
                        setStarIvSize((int) (mStarIvOriginWid * (1 - progress)), (int) (mStarIvOriginHeight * (1 - progress)));
                    }
                }
                if (value >= totalTime - 10) {
                    binding.starIv.setVisibility(View.GONE);
                }
            }
        });
        animator.start();

    // 改变星星ImageView的大小,LayoutParams不能弄错了
    private void setStarIvSize(int wid, int height) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) binding.starIv.getLayoutParams();
        lp.width = wid;
        lp.height = height;
        binding.starIv.setLayoutParams(lp);
    }

如果一个View在LinearLayout里,它的坐标没有那么容易获取。

下面的代码获取到的坐标是0,0。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
imageView.post(new Runnable() {
    @Override
    public void run() {
        int[] location = new int[2];
        imageView.getLocationOnScreen(location);
    }
});

创建自定义过渡动画 - Google

自动为布局更新添加动画 - Google

退出App

在登录界面,点击返回键即退出整个App。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private boolean mExitApp = false;

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        mExitApp = true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mExitApp) {
            System.exit(0);
        }
    }

crash

为了提高程序的健壮性,很多时候并不能过于相信服务器返回的结果。该加判空就判空。

如果服务器返回空的数据或者字段,要有对应的措施。

gc超时

该异常表示调用超时。

解决方案:一般是系统在gc时,调用对象的finalize超时导致

解决办法:

1.检查分析finalize的实现为什么耗时较高,修复它;

2.检查日志查看GC是否过于频繁,导致超时,减少内容开销,防止内存泄露。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
android.content.res.XmlBlock$Parser.finalize() timed out after 10 seconds

android.content.res.AssetManager.xmlBlockGone(AssetManager.java:500)

android.content.res.AssetManager.xmlBlockGone(AssetManager.java:500)
android.content.res.XmlBlock.decOpenCountLocked(XmlBlock.java:63)
android.content.res.XmlBlock.access$1600(XmlBlock.java:34)
android.content.res.XmlBlock$Parser.close(XmlBlock.java:448)
android.content.res.XmlBlock$Parser.finalize(XmlBlock.java:454)
java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:191)
java.lang.Daemons$FinalizerDaemon.run(Daemons.java:174)
java.lang.Thread.run(Thread.java:818)

RuntimeException: Cannot create an instance of class

使用了MVVM的框架,创建viewModel时报错。检查发现忘记复写方法initViewModel

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public MyViewModel initViewModel() {
    MyAppViewModelFactory factory = MyAppViewModelFactory.getInstance(getApplication());
    return ViewModelProviders.of(this, factory).get(MyViewModel.class);
}

ANR

死循环导致的ANR

之前业务逻辑中,有一个随机添加不重复字符串的功能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
while (needCheckList.size() < 3) {
    Random rd = new Random();
    String word = wordList.get(rd.nextInt(wordList.size()));
    if(!needCheckList.contains(word)) {
        needCheckList.add(word);
    }
    // .....
}

这段代码的效率不高。伪随机数不能保证高效地不重复地取到新的下标。

在某些性能较差的手机上,陷入多次循环后有可能导致anr。 anr message 表明此时CPU占用率超过100%。

我们使用Collections.shuffle(wordList);来代替伪随机数,也能实现随机取出字符串的效果。提高健壮性。

gradle

想在Terminal里使用gradlew命令,还得先在电脑上安装jdk。

现在(2019-11-18)想在官网下载个jdk,还得登录oracle账号。网速很慢,去别的地方下载jdk-8u181-windows-x64。

多渠道自动打包

假设我们有很多种渠道,每个渠道的manifestPlaceholders的内容都不同。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
productFlavors {
    xxx {
        manifestPlaceholders = [XX_ID  : "123",
                                XX_KEY : "key_key"]
    }
}

之前渠道少的时候,可以点击gradle task一个个来打包。

现在渠道种类多了(比如二十多个),再一个个点击就很累。想要一键打包或者一行命令打包,有什么成熟好用的多渠道打包方式呢?

我们尝试了美团点评的walle,号称是Android Signature V2 Scheme签名下的新一代渠道包打包神器

试着接入walle的姿势可能不对,打包不成功。此时看到有人说不支持多渠道不同的包名和配置manifestPlaceholders,暂时先不使用walle。

已经使用了Bugly,有很多形如assembleXxxRelease的任务。

我们可以在终端命令行里执行gradlew命令来打包。

Windows环境下就是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gradlew assembleXxxRelease

那么写一个bat脚本,把这几十个渠道包按顺序一个个打包出来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gradlew assembleXxxRelease && gradlew assembleYyyRelease && gradlew assembleZzzRelease

这个方法非常“暴力”,仅仅是替代了手动执行的过程。

框架

BindingCommand 问题

由于历史原因,App使用了一个MVVM框架。layout中可以绑定BindingCommand。

不知道是不是开发姿势不对,快速点击某个按钮时,对应的BindingCommand并不能立即响应。连续点击会错过点击事件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public BindingCommand myCommand = new BindingCommand(new BindingAction() {
    @Override
    public void call() {
        // my logic
    }
});

而换用setOnClickListener可以立刻监听到每一个点击事件。

为了追求响应速度,在某些地方采用设置监听器的方式了。

界面UI

android 跑马灯重复抖动的解决方法

解决的方法,在跑马灯控件外层,再嵌套一个布局控件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="55"
    android:orientation="horizontal">

    <com.rustfisher.view.MarqueeTextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:maxWidth="150dp"
        android:singleLine="true"
        android:text=""
        android:textSize="10sp" />

</LinearLayout>

EditText划词选词弹出菜单

et可选,弹出了系统的菜单。

et不可选,弹出了自定义的菜单。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
registerForContextMenu(mEt);
mEt.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
    @Override
    public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        Log.d(TAG, "onCreateContextMenu: selected: " + mEt.getSelectionStart() + ", " + mEt.getSelectionEnd()); // 都是0
        getMenuInflater().inflate(R.menu.et_menu, menu);
    }
});

et可选,弹出了自定义菜单。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mEt.setCustomSelectionActionModeCallback(genActionModeCallback1());

private ActionMode.Callback genActionModeCallback1() {
    return new ActionMode.Callback() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            Log.d(TAG, "onCreateActionMode:"
                    + " selected: " + mEt.getSelectionStart() + ", " + mEt.getSelectionEnd());
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            Log.d(TAG, "onPrepareActionMode: " + " selected: " + mEt.getSelectionStart() + ", " + mEt.getSelectionEnd());
            menu.clear();
            mode.getMenuInflater().inflate(R.menu.et_menu, menu);
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            Log.d(TAG, "onActionItemClicked: " + " selected: " + mEt.getSelectionStart() + ", " + mEt.getSelectionEnd());
            mode.finish();
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            Log.d(TAG, "onDestroyActionMode: " + " selected: " + mEt.getSelectionStart() + ", " + mEt.getSelectionEnd());
        }
    };
}

1+手机可以用,但小米手机无法弹出自定义菜单。此法不能通用。

竖直的进度条

https://stackoverflow.com/questions/3926395/android-set-a-progressbar-to-be-a-vertical-bar-instead-of-horizontal

获取statusbar高度

在Activity中获取DecorView。通过DecorView的位置来判断statusBar的高度。Activity别设置成全屏的就好。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void getStatusBarHeight() {
    Rect rectangle = new Rect();
    Window window = getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
    Log.d(TAG, "getStatusBarHeight: " + rectangle.top);
}

让statusbar不占位置,并设置成透明背景。

底下的虚拟系统按键(Home,back,menu)不能受影响。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">false</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

drawable - vector assets

通过引入svg文件得到的drawable,layout中直接设置src使用drawable。小米4c和红米6A手机屏幕上图像错乱。

改变ImageView的大小不起作用。清楚as缓存也不起作用。

如果不在layout中设置,而是在代码中setImageResource则显示正常。

设计界面

去花瓣网上找灵感。

比如设计列表界面,可以给每个项目增加一个小背景。可以是颜色,可以是背景图。

网络请求

设计接口获取数据

项目里用OKHttp框架来进行网络请求。返回结果被转化成对象Entity

同一个服务器返回里装有相同结构的A,B,C对象。它们的名字不一样,GsonFormat的时候是分开成3个类的。

为了让代码更简洁,把这3个对象进行抽象。

一开始是做了一个抽象类,让这3个类继承。但是OKHttp那边会报错。

然后改用了接口的方式。设计的接口里有一些通用方法。在Entity里让那3个类都实现这个接口,然后在方法中返回我们要的数据。

AsyncTask

资源分配

AsyncTask背后有一个线程池。调用了execute()并不能保证任务立刻被执行。

换用Thread。

App设置

分屏设置

如果不进行设置,默认是允许分屏的。这里我们把分屏给禁止。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="false"

添加在application标签里。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<application
    android:name=".app.MyApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:networkSecurityConfig="@xml/network_security_config"
    android:theme="@style/AppTheme">

adb

系统App

把apk放进root后的手机里,当做是系统app。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
F:\IE\MyApp0826\app\libs>adb root
F:\IE\MyApp0826\app\libs>adb remount
remount succeeded

F:\IE\MyApp0826\app\libs>adb shell mkdir /system/priv-app/MyApp
F:\IE\MyApp0826\app\libs>adb shell chmod 755 /system/priv-app/MyApp
F:\IE\MyApp0826\app\libs>adb shell chmod 644 /system/priv-app/MyApp/MyApp.apk
F:\IE\MyApp0826\app\libs>adb shell chmod 755 /system/priv-app/MyApp/lib
F:\IE\MyApp0826\app\libs>adb shell chmod 755 /system/priv-app/MyApp/lib/arm
F:\IE\MyApp0826\app\libs>adb shell sync
F:\IE\MyApp0826\app\libs>adb shell reboot

范围内随机数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Random rand = new Random(seed);
int random_integer = rand.nextInt(upperbound-lowerbound) + lowerbound;

内存泄漏

Handler与单例

单例模式加上Handler。有人把handler直接交给单例。长生命周期的一直持有短生命周期的对象,没法回收造成内存泄漏。

viewModel中有一个handler,而handler被单例持有。handler是直接实例化的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
aHandler = new Handler() {
    @Override
    public void handleMessage(@NonNull Message msg) {
        handleResult(msg);
    }
};

handleResult方法中使用了viewModel的数据列表。

这样在新建一个viewModel的时候,单例持有旧的handler,handler持有的还是旧的那个数据列表。

内存中就有2份不一样的数据列表。

修复方案:

首先不能让单例持有这个handler。

其次退出viewModel的时候,把handler中的消息清空。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
13 条评论
热度
最新
现在已经2022了,但是还是经常会回来看看,以后我应该是要参照你的自己写一个 : ) 希望允许转载(会声明
现在已经2022了,但是还是经常会回来看看,以后我应该是要参照你的自己写一个 : ) 希望允许转载(会声明
回复回复点赞举报
博主请问一下,hexo generate && hexo deploy之后出现 error failed to push some refs to 'ubuntu@120.53.9.241:/var/repo/hexo_static.git"怎么解决啊
博主请问一下,hexo generate && hexo deploy之后出现 error failed to push some refs to 'ubuntu@120.53.9.241:/var/repo/hexo_static.git"怎么解决啊
回复回复点赞举报
博主请问一下,按照步骤配置nginx后,访问ip出现“403 Forbiddennginx/1.14.0 (Ubuntu)”这个应该怎么解决啊
博主请问一下,按照步骤配置nginx后,访问ip出现“403 Forbiddennginx/1.14.0 (Ubuntu)”这个应该怎么解决啊
11点赞举报
Nginx重启下, 并确定 /var/www/hexo下有静态文件
Nginx重启下, 并确定 /var/www/hexo下有静态文件
回复回复点赞举报
博主请问一下 最后胚子和ubuntu@CVM 云服务器的IP地址:/var/repo/hexo_static CVM与ip地址之间有无空格,其次 这个ip地址是公网还是内网ip啊?
博主请问一下 最后胚子和ubuntu@CVM 云服务器的IP地址:/var/repo/hexo_static CVM与ip地址之间有无空格,其次 这个ip地址是公网还是内网ip啊?
11点赞举报
ubuntu@云主机公网IP:/var/repo/hexo_static.git
ubuntu@云主机公网IP:/var/repo/hexo_static.git
回复回复点赞举报
按照教程执行了最后一步之后提示:INFO 33 files generated in 755 ms,但是我的站还是不能访问,咋办?
按照教程执行了最后一步之后提示:INFO 33 files generated in 755 ms,但是我的站还是不能访问,咋办?
11点赞举报
执行下 hexo d
执行下 hexo d
回复回复点赞举报
Error: Permission denied (publickey).fatal: Could not read from remote repository. hexo d出现这个怎么解决
Error: Permission denied (publickey).fatal: Could not read from remote repository. hexo d出现这个怎么解决
22点赞举报
同问
同问
回复回复点赞举报
删除 c:\user\administrator\.ssh 文件, 重新生成公钥,并添加到 authoriz ... 文件中
删除 c:\user\administrator\.ssh 文件, 重新生成公钥,并添加到 authoriz ... 文件中
回复回复点赞举报
你好,我想咨询一个问题,就是我本身博客部署在 GitHub pages上的,现在想迁移到云服务上,按照你的步骤都成功了,在最后一步 hexo d 提交时提示:Everything up-to-date ,我不太懂hexo 的机制,希望能解答一下,谢谢。
你好,我想咨询一个问题,就是我本身博客部署在 GitHub pages上的,现在想迁移到云服务上,按照你的步骤都成功了,在最后一步 hexo d 提交时提示:Everything up-to-date ,我不太懂hexo 的机制,希望能解答一下,谢谢。
11点赞举报
需要先在任意位置处打开powershell, 从服务器上把`hexo_static`仓库克隆下来, 以此来将服务器地址添加到受信任的站点中。代码是```git clone ubuntu@server_ip:/var/repo/hexo_static.git```
需要先在任意位置处打开powershell, 从服务器上把`hexo_static`仓库克隆下来, 以此来将服务器地址添加到受信任的站点中。代码是```git clone ubuntu@server_ip:/var/repo/hexo_static.git```
回复回复点赞举报
推荐阅读
Hexo部署至服务器(Ubuntu 20.04)
本文将介绍如何从零开始,将Hexo项目部署到服务器(Ubuntu 20.04)上。
花猪
2022/02/22
2.9K1
Hexo部署至服务器(Ubuntu 20.04)
如何在Ubuntu 14.04上使用Hexo创建博客
Hexo是一个基于Node.js的静态博客框架。使用Hexo,您可以以博客文章的形式发布Markdown文档。博客帖子和内容被处理并转换为HTML / CSS,它来自默认或自定义模板主题文件(很像其他静态博客生成器,如Jekyll和Ghost)。Hexo中的所有软件都是模块化的,因此您可以准确安装和设置所需的软件。
木纸鸢
2018/09/25
1.3K0
Hexo之我的个人博客改用自己服务器搭建
最近小明介绍完自己用hexo+git搭建个人博客,大家好像更关心的是域名mynamecoder.com,不是应该关注技术嘛,让小明哭笑不得?,今天继续给大家讲一下如果觉得这两个代码托管平台打开加载太慢
程序员小明
2019/10/14
2.6K1
从零搭建Hexo博客并部署腾讯云服务器
腾讯云服务器已经买了好一阵子了,拖延到现在才搭博客,参考各个社区里挺多教程,最后选择使用Hexo来作为自己的博客框架,好处是不用自己造轮子,而且有很多漂亮的主题可以拿来用。今天上午把搭博客过程做个小结,希望对有想法要做自己的博客的同学们有一些帮助。
用户7978588
2020/12/19
2.4K0
Hexo博客的部署和使用
Hexo是一款快速、简洁且高效的博客框架,其基于Node.js让页面快速完成渲染,强大的API带来无限可能,丰富的插件和主题让建站更容易,生成的静态网页托管在GitHub等平台上还可以省去大量服务器费用。
M.Talen
2024/05/22
1650
Hexo博客的部署和使用
腾讯云服务器如何快速部署 Hexo 个人博客
你好,我是喵喵侠。作为一名热爱技术的开发者,我上大学那会儿就开始研究如何搭建个人博客了。经典的博客系统有WordPress、Typecho、Ghost等,这些部署起来也很简单,需要安装后台数据库,可以通过后台直接发布文章。对于前端开发人员来说,静态网站部署或许会更加简单一些,你只需要使用Markdown语法编写文章,加入一些博客框架特定的语法,就可以形成标题、关键词、主题样式、内容等配置。
喵喵侠
2024/11/30
1970
腾讯云服务器如何快速部署 Hexo 个人博客
The deployment of Hexo
Hexo的标签就是高效渲染+静态+简单,安装好后的后续文章的推送和页面的一些修改采用的是git方式的推送,通过密钥方式登录避免了每次推送更新都要输入密码的麻烦。安装过程主要分为服务器端的安装后本地客户端的安装,服务器端需要安装nginx+git+node.js,客户端的话是:git+node.js+hexo。
Tommonkey
2023/02/25
3600
如何快速部署国人开源的 Java 博客系统 Tale
本文介绍了如何在云服务器上部署一个开源博客系统——Tale。通过详细的步骤和截图,本文展示了如何从零开始搭建一个简单的博客,并利用Nginx和MySQL实现访问控制。同时,作者还分享了一个系统启动脚本,用于自动启动博客。最后,作者还提供了一些建议,包括如何为博客添加主题和插件,以及如何为云服务器设置访问权限。
EarlGrey
2017/02/28
12.1K1
如何快速部署国人开源的 Java 博客系统 Tale
如何搭建hexo博客到Linux云服务器
我是一个个人博客爱好者,平时有着记录自己折腾各种好玩东西过程的习惯,所以在大学期间我就搭建了一个自己的博客,刚开始入门用的是wordpress,用的是盗版的知更鸟主题,但随着时间推移,大概运行了一年时间,博客系统越来越臃肿,插件千奇百怪,学习成本较高,更为致命的是,需要大量的优化才能保证正常的加载速度(其实还是我太菜,不会优化,手动狗头),而且不能很好地支持markdown,违背了我写作的初衷,我在市面上开始寻找另外一款能够很好支持markdown语法的博客系统,此时typecho进入到了我的视线,相比于wordpress来讲,它更轻量化,而且很好的支持markdown语法,就这样,我再次转投到了typecho旗下,进行了大规模的迁移,再次运行了一年之久,然而新的问题随之而来,国外垃圾评论频出,加载速度太慢,markdown语法解析部分出问题(还是我太菜,不会前端自己开发解析),时至今日,我再次把目光投向了静态博客生成器,所谓博客生成器就是将markdown文件渲染成html静态文件,没有数据库的加持,全部博客页面纯静态,提升加载速度,抛弃臃肿插件,回归写作的本质,现在市面上比较出名的是hexo和hugo,两者相比,hexo更加成熟,玩的人更多,学习成本较低,所以我选择了hexo作为我的第三套博客系统。
tyrantlucifer
2022/03/23
1.5K0
如何搭建hexo博客到Linux云服务器
Hexo博客部署到Linux服务器上
以前Hexo博客是托管到github上,因为国内访问github速度有些慢,这次试着把博客部署到阿里云的服务器上。本地系统Windows10上需要安装node.js+hexo。下面做一个详细的介绍。
Lvshen
2022/05/05
6K0
Hexo博客部署到Linux服务器上
将 Hexo 部署在云服务器
将 Hexo 部署在云服务器 前言 众所周知,使用 GitHub Page 的访问速度令人发指,当然也有很多人选择部署到 Vercel,这便是我之前的选择,免费,同时还有着更快的速度。但说到底,云服务器往往是更好的选择,只要钱到位 😑。 使用宝塔面板可以比较方便快速的进行部署,不过我更想自己实际动手操作,也一边学习 Linux,就不使用了。 准备工作 本文假设你拥有 Hexo 建站相关的知识,相关的问题不再赘述,你也可以点击这里查看 Hexo 建站相关的知识。 在阅读本文之前,你需要做好以下准备:
EmoryHuang
2022/10/31
5.3K0
用树莓派做服务器运行博客网页
​ 手头有一块树莓派4B,为了不让树莓派闲着,我用它做一个网页服务器,挂载自己的个人网页,分享一下自己的部署过程
全栈程序员站长
2022/09/05
1.6K0
用树莓派做服务器运行博客网页
将Hexo部署到腾讯云轻量应用服务器
进入腾讯云,点击右上角控制台,选择轻量应用服务器(如果没有的话,就直接使用上面的搜索功能) 找到自己的服务器,点击 更多→管理,然后选择重置密码,重置初始密码
十玖八柒
2022/08/01
8K1
将Hexo部署到腾讯云轻量应用服务器
将个人博客迁移到云服务器上
之前通过github 和coding 来搭建的个人博客,但是搜索引擎一直不是很好,并且总感觉不稳定,访问很慢。最近刚刚买了一个云服务器,所以就打算将个人博客迁移到云服务器上。
程序员爱酸奶
2020/03/16
2.1K0
将个人博客迁移到云服务器上
【玩转Lighthouse】Docker与Hexo博客的部署实战
之所以选用轻量应用服务器,是因为相比起云服务器CVM,轻量应用服务器更加精简便捷易用,创建轻量服务器时更有流行的开源软件打包镜像,实现一键完成应用的构建部署。对于我们这种低负载的个人以及中小企业来说,成本低,性价比更加适合。废话不多说,让我们直接开始吧。
用户1542270
2022/04/27
2.9K1
Hexo 博客部署到腾讯云教程
本文首发于我的个人博客:『不羁阁』文章链接:传送门 本篇内容用来讲述如何将 hexo 博客部署到腾讯云的服务器上。 只要通过三步即可成功部署: 云服务器端 git 的配置 Nginx 的配置 本地端 hexo 的设置更改 前言 最近趁着腾讯云在做活动,买了3年的服务器。正好自己的博客之前是搭建在 coding 上的,现在也可以顺便部署到腾讯云上了。其实过程蛮简单的,即使,你是个对后台一窍不通的小白,也能很容易部署成功。顺便安利下腾讯云的活动。通过以下两步,即可360块钱买到40个月(三年半)的云服务
程序员充电站
2018/05/31
7.5K1
Hexo博客部署腾讯云服务器
设置的密码看不到,你直接输入就可以了。这里我设置的密码太简单了会有这样的提示。不用关心直接输入,看到成功提示即可。
程序员Leo
2023/08/07
5450
Hexo博客部署腾讯云服务器
【腾讯云的1001种玩法】Hello Hexo之静态博客搭建+自动部署
饶文津
2017/04/13
4.9K0
Gitee + Nginx + Hexo +LeanCloud搭建博客
​ 需求一:首先呢,当然是在浏览器中输入ip(101.42.229.55),就可以访问页面~。 ​ 1.需要有自己的Linux云服务器(我用的腾讯云服务器,几十块) ​ 2.在云服务器上部署nginx(部署个人博客,总不能一直session挂着进程吧,需要nginx来代理服务)
酒楼
2023/05/30
5500
Gitee + Nginx + Hexo +LeanCloud搭建博客
将Hexo部署到云服务器(使用宝塔面板)
本来Hexo是部署在GitHub上的(可以看我之前文章Hexo搭建静态博客 - Taitres' Blog包括了Hexo的基本使用),但是访问太慢了,并且想折腾一下,还想整个个人云盘,就买了个腾讯云的轻量应用服务器,把Hexo搬过来了,看了很多文章,记录下最终的解决方案。
Taitres
2021/05/13
14.2K4
推荐阅读
相关推荐
Hexo部署至服务器(Ubuntu 20.04)
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 音频
  • 自定义ViewGroup
    • crash ViewGroup.resetResolvedLayoutDirection
  • Bugly热更新
  • Assets遍历文件
  • 语音识别方案
  • 下载文件
  • 限速下载
  • 下载安装apk
  • 修改Android系统镜像(img)
  • 动画效果
    • 属性动画 - 星星飞行
  • 退出App
  • crash
    • gc超时
    • RuntimeException: Cannot create an instance of class
  • ANR
    • 死循环导致的ANR
  • gradle
    • 多渠道自动打包
  • 框架
    • BindingCommand 问题
  • 界面UI
    • android 跑马灯重复抖动的解决方法
    • EditText划词选词弹出菜单
    • 竖直的进度条
    • 获取statusbar高度
    • drawable - vector assets
    • 设计界面
  • 网络请求
    • 设计接口获取数据
  • AsyncTask
    • 资源分配
  • App设置
    • 分屏设置
  • adb
    • 系统App
    • 范围内随机数
  • 内存泄漏
    • Handler与单例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档