1.首先看一下效果

1.1做成了一个GIF

  

1.2.我用格式工厂有点问题,大小无法调到手机这样的大小,目前还没有解决方案。

1.3.网上有免费的MP4->GIF,参考一下这个网站吧。

1.4.讲解一下这个图片吧,首先是从话题中点击了其中一张图片,进入图片Activity,

   然后可以自由放大,自由翻转。

2.分析一下继承的BaseImageActivity

2.1因为ImageActivity继承了BaseImageActivtiy,首先看看源代码。

/*
* Copyright 2017 GcsSloop
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Last modified 2017-03-15 20:02:59
*
* GitHub: https://github.com/GcsSloop
* Website: http://www.gcssloop.com
* Weibo: http://weibo.com/GcsSloop
*/ package com.gcssloop.diycode.base.app; import android.content.Intent; import java.util.ArrayList; /**
* 对数据进行预处理
*/
public abstract class BaseImageActivity extends BaseActivity {
public static final String ALL_IMAGE_URLS = "all_images";
public static final String CURRENT_IMAGE_URL = "current_image"; protected static final String MODE_NORMAL = "normal";
protected static final String MODE_ERROR = "error";
protected String mCurrentMode = MODE_NORMAL; protected ArrayList<String> images = new ArrayList<>(); // 所有图片
protected String current_image_url = null; // 当前图片
protected int current_image_position = 0; // 当前图片位置 @Override
protected void initDatas() {
super.initDatas(); // 初始化图片 url 和 图片集合,保证两个数据都存在
Intent intent = getIntent(); // 没有传递当前图片,设置模式为错误
String imageUrl = intent.getStringExtra(CURRENT_IMAGE_URL);
if (imageUrl == null || imageUrl.isEmpty()) {
toastShort("没有传递图片链接");
mCurrentMode = MODE_ERROR;
return;
}
mCurrentMode = MODE_NORMAL; ArrayList<String> temp = intent.getStringArrayListExtra(ALL_IMAGE_URLS);
if (temp == null || temp.size() <= 0) {
// 记录当前图片,计算位置
images.clear();
images.add(imageUrl);
} else if (temp.size() > 0) {
// 如果图片集合大于0
images = new ArrayList<>(temp);
} if (!images.contains(imageUrl)) {
images.add(imageUrl);
} current_image_url = imageUrl;
current_image_position = images.indexOf(current_image_url);
}
}

2.2这里需要回顾一下BaseActivity。

  BaseActivity==>主要提供了项目本身API提供的Diycode类,ViewHolder类,Toast类,两个抽象方法。ActionBar。结束

当前活动。

打开活动。

2.3.私有成员变量。

  ·存放图片链接的一个ArrayList<String>

  ·存放当前图片的链接current_image_url

  ·存放当前图片位置,整型current_image_positon

2.4.注意点,Override一个在基类中已经实现过的函数。

  重载,也是可以Override的。以前理解的Override就是抽象方法,接口方法。这里又涨知识了。

  如果写了一个父类中有的方法,就相当于重载了父类中的方法,就不会执行父类中的那个方法,而是执行自己的方法了。

名字是一样的。

2.5.在BaseActivity中写了一个空的initDatas方法。而且规定了这个方法执行的顺序。

  然后在子类BaseImageActivity中重载这个方法。

  这个类主要处理图片数据的。

2.6分析这个重载方法。

  

  

  2.6.1首先从intent中获得当前图片,如果没有,设置模式为错误。否则,设置模式为正常。

  2.6.2然后从intent中获得所有图片集合,如果没有,就把当前图片加进images去,如果有,就将集合加到一个images中。

  2.6.3然后它还判断了一下images中是否包含了当前url,应该是双保险吧,感觉没必要。

  2.6.4最后,就把当前图片和当前位置更新了一下。

3.分析一下图片缓存DiskImageCache

3.1首先看看在ImageActivity中定义的一个变量。DiskImageCache mCache;源代码如下:

/*
* Copyright 2017 GcsSloop
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Last modified 2017-03-12 00:56:52
*
* GitHub: https://github.com/GcsSloop
* Website: http://www.gcssloop.com
* Weibo: http://weibo.com/GcsSloop
*/ package com.gcssloop.diycode.base.webview; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;
import android.support.annotation.NonNull;
import android.util.Log; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Comparator; public class DiskImageCache {
private static final String CACHE_SUFFIX = ".cache"; private static final int MB = 1024 * 1024;
private static final int CACHE_SIZE = 50; // 缓存占用空间大小
private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10; // 为 SD 卡保留多少空间 private File cacheDir; public DiskImageCache(Context context) {
cacheDir = getDiskCacheDir(context, "web-image");
// 整理缓存
organizeCache(cacheDir);
} /**
* 从缓存中获取图片
**/
public Bitmap getBitmap(final String key) {
final String path = getCachePath(key);
File file = new File(path);
if (file.exists()) {
Bitmap bmp = BitmapFactory.decodeFile(path);
if (bmp == null) {
file.delete();
} else {
updateFileTime(path);
return bmp;
}
}
return null;
} /**
* 将图片存入文件缓存
**/
public void saveBitmap(String key, Bitmap bm) {
if (bm == null) {
return;
}
//判断sdcard上的空间
if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
return; //SD空间不足
}
File file = new File(getCachePath(key));
try {
file.createNewFile();
OutputStream outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
Log.w("ImageFileCache", "FileNotFoundException");
} catch (IOException e) {
Log.w("ImageFileCache", "IOException");
}
} /**
* 保存 bytes 数据
*
* @param key url
* @param bytes bytes 数据
*/
public void saveBytes(String key, byte[] bytes) {
if (bytes == null) {
return;
}
//判断sdcard上的空间
if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
return; //SD空间不足
}
File file = new File(getCachePath(key));
try {
file.createNewFile();
OutputStream outStream = new FileOutputStream(file);
outStream.write(bytes);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
Log.w("ImageFileCache", "FileNotFoundException");
} catch (IOException e) {
Log.w("ImageFileCache", "IOException");
}
} /**
* 获取一个本地缓存的输入流
*
* @param key url
* @return FileInputStream
*/
public FileInputStream getStream(String key) {
File file = new File(getCachePath(key));
if (!file.exists())
return null;
try {
FileInputStream inputStream = new FileInputStream(file);
return inputStream;
} catch (FileNotFoundException e) {
Log.e("getStream", "FileNotFoundException");
e.printStackTrace();
}
return null;
} /**
* 获取本地缓存路径
*
* @param key url
* @return 路径
*/
public String getDiskPath(String key) {
File file = new File(getCachePath(key));
if (!file.exists())
return null;
return file.getAbsolutePath();
} /**
* 是否有缓存
*
* @param key url
* @return 是否有缓存
*/
public boolean hasCache(String key) {
File file = new File(getCachePath(key));
return file.exists();
} /**
* 计算存储目录下的文件大小,
* 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
* 那么删除40%最近没有被使用的文件
*/
private boolean organizeCache(@NonNull File cacheDir) {
File[] files = cacheDir.listFiles();
if (files == null) {
return true;
}
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return false;
} int dirSize = 0;
for (int i = 0; i < files.length; i++) {
if (files[i].getName().contains(CACHE_SUFFIX)) {
dirSize += files[i].length();
}
} if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
int removeFactor = (int) ((0.4 * files.length) + 1);
Arrays.sort(files, new FileLastModifSort());
for (int i = 0; i < removeFactor; i++) {
if (files[i].getName().contains(CACHE_SUFFIX)) {
files[i].delete();
}
}
} if (freeSpaceOnSd() <= CACHE_SIZE) {
return false;
} return true;
} /**
* 修改文件的最后修改时间
**/
public void updateFileTime(String path) {
File file = new File(path);
long newModifiedTime = System.currentTimeMillis();
file.setLastModified(newModifiedTime);
} /**
* 计算sdcard上的剩余空间
**/
private int freeSpaceOnSd() {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
return (int) sdFreeMB;
} /**
* 根据文件的最后修改时间进行排序
*/
private class FileLastModifSort implements Comparator<File> {
public int compare(File arg0, File arg1) {
if (arg0.lastModified() > arg1.lastModified()) {
return 1;
} else if (arg0.lastModified() == arg1.lastModified()) {
return 0;
} else {
return -1;
}
}
} /**
* 获取缓存文件的绝对路径
*/
private String getCachePath(String key) {
return cacheDir.getAbsolutePath() + File.separator + convertKey(key);
} /**
* 获取磁盘缓存文件夹 优先获取外置磁盘
*
* @param context 上下文
* @param uniqueName 自定义名字
*/
public File getDiskCacheDir(Context context, String uniqueName) {
String cachePath;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
File cacheDir = new File(cachePath + File.separator + uniqueName);
if (!cacheDir.exists())
cacheDir.mkdir();
return cacheDir;
} /**
* 哈希编码
*/
public String convertKey(String key) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey + CACHE_SUFFIX;
} private String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
} }

3.2定义的常量及变量预览。

3.3.构造函数就一个。实现方法在后面。

  

3.4.如何从缓存中获取图片(通过一个String返回一个Bitmap),这个项目暂时没有用到。

  

3.5.如何将图片存入文件缓存?(将一个bitmap,存放一个缓存路径为一个key下)

  

3.6.如何保存bytes数据?(也是存放到一个key中)

  

3.7.如何获取一个本地缓存的输入流?(通过一个key获得FileInputStream)

  

3.8.如何获取本地缓存路径?(通过一个key得到一个String)

  

3.9.如何判断是否有缓存?(通过一个key返回boolean)

  

3.10.然后是关键的整理存储空间了。这个删除文件很关键,不然数据会越来越大的。

  

  

3.11.如何修改文件的最后修改时间?(参数为文件path)

  

3.12.如何计算sdcard上的剩余空间?

  

3.13.如何根据文件的最后修改时间进行排序?(继承了一个Comparator<File>的内部类)

  

  FileLastModifSort其实就是一个类,类中有一个比较的函数,有两个File的参数,比较哪个更加最后而已。

3.14.如何获取缓存文件的绝对路径?(通过key得到一个String)

  

3.15.如何获取磁盘缓存文件夹,优先获取外置磁盘?(参数为context和一个string返回一个File)

  

3.16.什么是哈希编码?(参数为key返回一个String)

  

  通过MD5加密后加了一个后缀为.cache,返回这个字符串。

3.17.bytes数组转化为哈希String?(参数为byte[]返回一个String)

  

  这个在3.16.哈希编码中用到了,就是系统函数很多会转化为bytes,这个函数就是将byte[]类型的数据整合成String,

然后再处理逻辑。

  这个DiskImageCache比较长,主要处理的就是一些缓存问题了,图片缓存,和本地的存储器挂钩了,所以就有很多函数

要调用。

4.回到ImageActivity

4.1这里首先复写了一个getLayoutId,返回一个资源id,其实就是ImageActivity布局

  贴一下activity_image源代码。

  

<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2017 GcsSloop
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ Last modified 2017-03-15 23:45:17
~
~ GitHub: https://github.com/GcsSloop
~ Website: http://www.gcssloop.com
~ Weibo: http://weibo.com/GcsSloop
--> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.gcssloop.diycode.activity.ImageActivity"> <android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager> <com.rd.PageIndicatorView
android:id="@+id/pageIndicator"
android:layout_marginBottom="16dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:piv_viewPager="@id/view_pager"
app:piv_animationType="worm"
app:piv_autoVisibility="false"
app:piv_radius="4dp"
app:piv_padding="12dp"
app:piv_unselectedColor="@color/diy_gray2"
app:piv_selectedColor="@color/diy_red"
/> </RelativeLayout> </LinearLayout>

4.2分析一下布局代码的结构

  

4.3.和真实页面对比一下。

  

4.4.这里有一个新的知识点==>PageIndicatorView

  可以参考一下这篇文章。

  这是一个开源框架。挺不错的。简单实用。

  作用就是当页面在切换时,一个提示作用,下面的小红点会告诉用户这是第几张图或者第几个页面。

4.5.然后是复写一个initViews方法。

  4.5.1.注意,这个函数在initDatas之后调用。initDatas()函数在BaseImageActivity中调用了。  

  4.5.2.这里面通过setTitle设置了标题栏的查看图片。

  4.5.3.这里从参数ViewHolder中获得了布局中的ViewPager,显然ViewHolder中BaseActivity中定义

     然后ViewHolder初始化其实也是在BaseActivity中进行的,利用了一个抽象函数getLayoutId()

     然后initData(),然后initViews(),所以这个ImageActivity才能直接获得这个ViewPager的Id。

         

  4.5.4.这里看一下initViews中的部分代码。

     

     对于getLayoutInflater不太理解,参考一下这篇文章

     4.5.4.1.它的作用类似于findViewById()。

     4.5.4.2.LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化。

     4.5.4.3.FindViewById是找xml布局文件下的具体widget控件(如Button、TextView等)

  4.5.5.这里继续initViews中的部分代码。

    

    4.5.5.1.这里是在ImageActivity中定义的布局文件中的viewPager设置适配器的过程。

    4.5.5.2.首先是复写了getCount方法,直接返回图片的张数。

    4.5.5.3.然后是复写了isViewFromObject方法,两个参数(View,Object),使两者相等。

    4.5.5.4.然后复写了一个关键的函数,instantiateItem(ViewGroup,int)

       

        对于这个复写函数不明白的,可以参考一下这篇文章。

    4.5.5.6.这里不得不提一下的是PhotoView。

        也是第三方开源库,支持双指缩放,旋转。

        使用方法点击这里

        github原地址点击这里。

        看一下效果图吧!

        

   4.5.5.7.分析一下instantiateItem==>这个方法返回一个对象,这个对象表明了PagerAdapter适配器选

        择那个对象放在当前的ViewPager中。

        然后这里还处理了缓存,如果缓存中有,就利用Glide.with(context).load(file).into()

        如果缓存中没有,就利用Glide.with(context).load(图片url).into()方法       

        然后将这个photoView添加到容器中,这个容器就是instantiateItem中的第一个参数。

   4.5.5.8.分析一下复写的destroyItem()方法,3个参数(ViewGroup,int,Object)

        这个方法,是从ViewGroup中移除当前View。

   4.5.5.9.然后将viewPager确定到第几项。

        调用了基类BaseImageActivity中的静态常量current_image_position。

        这样可以确定指示剂的位置。

 4.6.然后回到ImageActivity中,最后一个函数是loadImage(string,photoView)

      作用:给一个url和一个photoView,加载一张图到photoView中。

      这里用到了一个第三方库。图片加载库。

      Glide用法详解点击这里。

      Glide的原地址点击这里。

      源码如下:

      

      这个应该是设置了缓存策略。

      

      

5.总结一下

5.1.首先理解一下哪里会用到ImageActivity这个活动,这个活动不是局限于某一个模块,而是所有地方,只要包含了图片

  的地方,都是有可能调用intent来跳转到这里的。所以这个有点像之前做的大学喵,点击图片查看大图,支持缩放。

5.2.然后理解一下为什么这个ImageActivity要继承一个BaseImageActivity,这个BaseImageActivity实际上是一个抽象类,

  定义了所有图片数据,所以真实数据在这里面处理,确定当前图片url,当前是第几个图片。

5.3.然后定义了一个DiskImageCache,主要是处理图片缓存的,基本上每个项目都会涉及到图片缓存,而且这些方法都是

  必须实现而且基本一样,所以今后的项目也可以参考一下这个类,封装好的,耦合很低。

5.4.然后是一个imageActivity的布局,通过实现了BaseActivity中的抽象函数getLayoutId,来获得这个布局的资源id。

  然后在initViews中的参数holder中,利用holder.get(R.id.view_pager)就能访问到这个ViewPager。

5.5.初始化view,注意是在initDatas调用之后,因为有了数据,才能填充到真实的视图。这里可以setTilte()来设置标题。

  然后就是一些缓存处理了。

5.6.真正的图片要加载处理,必须要有一个adapter,所以这里new了一个PagerAdapter,实现了4个必须实现的方法。主要

  逻辑在instantiateItem(ViewGroup container,int position)中处理,比如开启photoView缩放功能。以及缓存处理。

5.7.initViews函数执行结束之前一定要设置这个viewPager当前的页面,调用setCurrentItem(int)即可。

  这个int其实是在父类中定义,因为这个是继承了父类,也可以直接调用父类中的变量。

5.8.最后是一个图片缓存策略,因为是灰色的,也没有执行,可以也不是必须要实现的。但是要是不得不说Glide有点强大,

  特别是处理图片问题,图片缓存问题,图片加载问题。有空再深究一下。

Diycode开源项目 ImageActivity分析的更多相关文章

  1. Diycode开源项目 BaseApplication分析+LeakCanary第三方+CrashHandler自定义异常处理

    1.BaseApplication整个应用的开始 1.1.看一下代码 /* * Copyright 2017 GcsSloop * * Licensed under the Apache Licens ...

  2. DiyCode开源项目 BaseActivity 分析

    1.首先将这个项目的BaseActivity源码拷贝过来. /* * Copyright 2017 GcsSloop * * Licensed under the Apache License, Ve ...

  3. Diycode开源项目 TopicContentActivity分析

    1.效果预览以及布局分析 1.1.实际效果预览 左侧话题列表的布局是通过TopicProvider来实现的,所以当初分析话题列表就没有看到布局. 这里的话题内容不是一个ListView,故要自己布局. ...

  4. Diycode开源项目 UserActivity分析

    1.效果预览 1.1.实际界面预览 1.2. 这是MainActivity中的代码 这里执行了跳转到自己的用户界面的功能. 1.3.点击头像或者用户名跳转到别人的页面 UserActivity的结构由 ...

  5. Diycode开源项目 LoginActivity分析

    1.首先看一下效果 1.1.预览一下真实页面 1.2.分析一下: 要求输入Email或者用户名,点击编辑框,弹出键盘,默认先进入输入Email或用户名编辑框. 点击密码后,密码字样网上浮动一段距离,E ...

  6. Diycode开源项目 MainActivity分析

    1.分析MainActivity整体结构 1.1.首先看一下这个界面的整体效果. 1.2.活动源代码如下 /* * Copyright 2017 GcsSloop * * Licensed under ...

  7. DiyCode开源项目 AboutActivity分析

    1.首先看一下效果 这是手机上显示的效果: 1.1首先是一个标题栏,左侧一个左箭头,然后一个图标. 1.2然后下方是一个可以滑动的页面. 1.3分成了7个部分. 1.4DiyCode的图标. 1.5然 ...

  8. DiyCode开源项目 TopicActivity 分析

    1.首先看看TopActivity效果.    2.TopicActivity是一个继承BaseActivity的.前面分析过BaseActivity了.主要有一个标题栏,有返回的图标. 3.贴一下T ...

  9. Diycode开源项目 SitesListFragment分析

    1.效果预览 1.1.网站列表实际界面 1.2.注意这个界面没有继承SimpleRefreshRecycleFragment 前面的话题和新闻继承了SimpleRefreshRecyclerFragm ...

随机推荐

  1. jquery jquery中是否加()的问题

    自己总结的,慢慢修改再: 1带上()代表立即执行 去掉()代表当有事件发生的时候,我再执行

  2. [翻译] Facebook HHVM 团队封闭开发三周成果展

    本人翻译的一篇文章,首发于伯乐在线. [补充信息]HipHop for PHP是一系列PHP脚本语言的程式码转换器的集合,它包含HPHPc.HPHPi.HPHPd以及HHVM,这四个脚本引擎各有所不同 ...

  3. css 选择器 & UI元素的伪类选择器 & 伪元素选择器

    UI元素的伪类选择器 1. :focus  用来选取获取焦点事件 2. :enabled 用来指定当元素处于可用状态时的样式 3. :disable  用来指定元素处于不可用时的状态    表单里应用 ...

  4. Linux 下查找指令

    原文链接:http://www.cnblogs.com/sunleecn/archive/2011/11/01/2232210.html whereis <程序名称>查找软件的安装路径-b ...

  5. (转载)C#中的lock关键字

    lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. 先来看看执行过程,代码示例如下: 假设线程A先执行,线程B稍微慢一点.线程A执 ...

  6. cocos2d-x 学习资料汇总

    cocos2d-x配置问题 - 我要飞的更高 - 博客频道 - CSDN.NET Cocos2d-x win7 + vs2010 配置图文详解(亲测) - 子龙山人 - 博客园 WINDONWS7+V ...

  7. alias 新的命令='原命令 -选项/参数'。举例说明,alias l=‘ls -lsh' 将重新定义 ls 命令,现在只需输入 l 就可以列目录了。

    alias 新的命令='原命令 -选项/参数'.举例说明,alias l=‘ls -lsh' 将重新定义 ls 命令,现在只需输入 l 就可以列目录了.

  8. HTML和CSS中一些有趣的

    CSS Rese http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css <link rel="styleshe ...

  9. Ubuntu 16.04 开启休眠功能

    因为休眠功能在部分计算机无法正常工作,所以Ubuntu默认是不开启休眠功能. 要想开启休眠功能先进行如下测试: 1.先检查是否有交换分区(swap),如果有确认交换分区至少和实际可用内存一样大. 2. ...

  10. Java的几种加载驱动的方法

    1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 2.DriverManager.registerD ...