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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章