WeChat 开源项目技术点总结整理


项目目录结构图:

这里写图片描述
目录:

1. 项目 build.gradle---查看项目主要涉及到哪些第三方库
2. 将Html文本转换成能正常显示的
3. 启动定时服务

一、项目 build.gradle—查看项目主要涉及到哪些第三方库

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'org.jsoup:jsoup:1.9.2'
    compile 'com.android.support:cardview-v7:24.0.0'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
// MaterialDesignDialog
    compile 'com.lb:materialdesigndialog:1.0.1'
// lb封装的工具库
    compile 'com.lb:utils:1.0.2'
// nohttp 网络请求框架
    compile 'com.yolanda.nohttp:nohttp:1.0.0'
// 点赞
    compile 'com.sackcentury:shinebutton:0.1.2'
}

二、将Html文本转换成能正常显示的Text

String desc = Html.fromHtml(englishBean.getDesc()).toString();

三、启动定时服务

1. 清单文件注册:
// 注册service 
<service android:name=".service.TimingTaskService" />

// 静态注册接收器   
<receiver  android:name=".receiver.TimingTaskReceiver" android:exported="true">
  <intent-filter android:priority="999">
  <action android:name="com.lb.wecharenglish.getRemoteData" />
  </intent-filter>
</receiver>
2、在MainActivity 中启动服务:
Intent service = new Intent(mContext, TimingTaskService.class);
startService(service);
 3、定时任务 TimingTaskService:
* 类描述:后台定时任务,每隔一段时间请求网络数据<br>
*/
public class TimingTaskService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        timingTask(this);
        return super.onStartCommand(intent, flags, startId);
    }

    private void timingTask(Context context) {
        Intent intent = new Intent(getPackageName() + ".getRemoteData");
        PendingIntent sender = PendingIntent.getBroadcast(context,
                0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        // Schedule the alarm!
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 8);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        // 间隔时间
        int interval = 1000 * 60 * 60 * 4;  // 4h
        // setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
        am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                interval, sender);
    }
}

// 关于系统服务提醒器 http://blog.csdn.net/wangxingwu_314/article/details/8060312

4、接收器开一个工作线程执行耗时网络操作

public class TimingTaskReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
        LogUtil.e(this, "接收到广播");
        String action = intent.getAction();
        if ((context.getPackageName() + ".getRemoteData").equals(action)) {
            new Thread() {
                @Override
                public void run() {
                    // 获取远端数据
                    List<EnglishBean> remoteDatas = new EnglishServer().getDataFromRemote();
                    // 遍历并添加到数据库
                    for (EnglishBean bean : remoteDatas) {
                        // 查询数据库是否包含该条数据
                        EnglishBean dbBean = new EnglishServer().findById(context, bean.getId());
                        if (null == dbBean) {
                            // 需要发出状态栏通知
                            LogUtil.e(this, "显示通知");
                            showNewNotification(context);
                        }
                        // 添加进数据库操作
                        new EnglishServer().add(context, bean);
                    }
                }
            }.start();
        } else {
            LogUtil.e(this, "action 不一致");
            LogUtil.e(this, "action=" + action);
        }
    }

/** * 状态栏显示一条新通知 * @param context 上下文对象 */
private void showNewNotification(Context context, int id, EnglishBean bean) {
    // 使用通知推送消息
    Notification.Builder builder = new Notification.Builder(context);
    // 设置消息属性
    // 必须设置的属性:小图标 标题 内容
    builder.setSmallIcon(R.mipmap.ic_launcher);
    builder.setContentTitle(bean.getTitle());
    // noinspection deprecation
    builder.setContentText(Html.fromHtml(bean.getDesc()));
    //创建一个通知对象
    Notification notification = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
        notification = builder.build();
    }
    // 使用通知管理器发送一条通知
    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(id, notification);
  }
}

四、加载图片相关配置

//设置启动图片,使用ImageLoader 防止内存溢出
ImageLoader.getInstance().displayImage("drawable://" + R.drawable.splash_pic,
        iv_splash_pic, ImageLoaderOptions.fadein_options);
//延迟3秒进入主页面
mHandler.sendEmptyMessageDelayed(ENTER_HOME, 3 * 1000);


   /** * 显示图片的所有配置 * @return */
    private DisplayImageOptions getWholeOptions() {
        DisplayImageOptions options = new DisplayImageOptions.Builder() 
        .showImageOnLoading(R.drawable.loading) //设置图片在下载期间显示的图片 
        .showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片 
        .showImageOnFail(R.drawable.error)  //设置图片加载/解码过程中错误时候显示的图片
        .cacheInMemory(true)//设置下载的图片是否缓存在内存中 
        .cacheOnDisk(true)//设置下载的图片是否缓存在SD卡中 
        .considerExifParams(true)  //是否考虑JPEG图像EXIF参数(旋转,翻转)
        .imageScaleType(ImageScaleType.IN_SAMPLE_INT)//设置图片以如何的编码方式显示 
        .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型
        //.decodingOptions(BitmapFactory.Options decodingOptions)//设置图片的解码配置 
        .delayBeforeLoading(0)//int delayInMillis为你设置的下载前的延迟时间
        //设置图片加入缓存前,对bitmap进行设置 
        //.preProcessor(BitmapProcessor preProcessor) 
        .resetViewBeforeLoading(true)//设置图片在下载前是否重置,复位 
        .displayer(new RoundedBitmapDisplayer(20))//不推荐用!!!!是否设置为圆角,弧度为多少 
        .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间,可能会出现闪动
        .build();//构建完成

        return options;
    }

//图片加载方式
displayer(BitmapDisplayer displayer)  // 设置图片的显示方式,如:
.displayer(new FadeInBitmapDisplayer(100))
其中,displayer的选择值:

     RoundedBitmapDisplayer(int roundPixels)设置圆角图片,不推荐!!!
              FakeBitmapDisplayer()这个类什么都没做
              FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间
     SimpleBitmapDisplayer()正常显示一张图片

//图片加载时监听
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() { 
    @Override 
    public void onLoadingStarted() { 
      //开始加载的时候执行 } 
    @Override 
    public void onLoadingFailed(FailReason failReason) {       
      //加载失败的时候执行 } 
    @Override 
    public void onLoadingComplete(Bitmap loadedImage) { 
      //加载成功的时候执行 } 
    @Override 
    public void onLoadingCancelled() { 
      //加载取消的时候执行 
    }});

//避免内存泄漏
@Override
protected void onDestroy() {
    mHandler.removeCallbacksAndMessages(null);
    super.onDestroy();
}

五、设置apk 生成方式

applicationVariants.all { variant -> variant.outputs.each { output -> def oldFile = output.outputFile
// edian_channel_01_v1.1.6_360手机助手
            //1.创建 edian_v
            def firstName = "everyday_v";

            //3.获取清单文件中的版本号
            def versionName = versionName;
            //4.根基标示渠道号填写对应的渠道商店

            //5.构建类型 是否是debug等
            def buildType = "";
            if (variant.buildType.name.equals('release')) {
                buildType = "release_";
            } else if (variant.buildType.name.equals('debug')) {
                buildType = "debug_";
            }
            def releaseApkName = buildType + firstName + versionName  + '.apk'

// + "_" + getDate()
            output.outputFile = new File(oldFile.parent as File, releaseApkName)
        }
    }

六、播放网络音频

final MediaPlayer player = new MediaPlayer();

player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        player.start();
    }
});

try {
    player.setDataSource("https://mp.weixin.qq.com/cgi-bin/readtemplate?t=tmpl/audio_tmpl&name=132&play_length=04:31");
} catch (Exception e) {
    e.printStackTrace();
}
player.prepareAsync();

七、使用noHttp 网络框架建立下载任务

private DownloadRequest downloadRequest;

@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case START_DOWNLOAD:
                pb_setting_synchronousing.setVisibility(View.VISIBLE);
                break;
            case DOWNLOAD_FINISH:
                pb_setting_synchronousing.setVisibility(View.GONE);
                break;
        }
    }
};


downloadRequest = NoHttp.createDownloadRequest(url, filePath, fileName, true, false);
// what 区分下载
// downloadRequest 下载请求对象
// downloadListener 下载监听
NoHttp.newDownloadQueue(2).add(0, downloadRequest, new DownloadListener() {
    @Override
    public void onDownloadError(int what, Exception exception) {
        LogUtil.log(this, exception);
        mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
        ToastUtil.showShortToast(mContext, "同步远程数据库失败,请重试");
    }

    @Override
    public void onStart(int what, boolean isResume, long rangeSize, Headers responseHeaders, long allCount) {
        LogUtil.log(this, "开始下载");
        mHandler.sendEmptyMessage(START_DOWNLOAD);
    }

    @Override
    public void onProgress(int what, int progress, long fileCount) {
        // 更新下载进度
    }

    @Override
    public void onFinish(int what, String filePath) {
        //下载完成,打开数据库
        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(filePath, null);
        final int count = new EnglishServer().copyDataFromDatabas(mContext, db);
        db.close();
        //删除已经下载的数据
        File file = new File(filePath);
        //noinspection ResultOfMethodCallIgnored
        file.delete();
        ToastUtil.showShortToast(mContext, "更新了" + count + "条数据");
        mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
    }

    @Override
    public void onCancel(int what) {
        LogUtil.log(this, "下载取消");
        pb_setting_synchronousing.setVisibility(View.GONE);
    }
});

感谢作者的分享。项目地址:https://github.com/291700351/WeCharEnglish


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: