[置顶] 开发总结

  1. 改变适配器Adapter内容时不要在后台线程中,必须在UI线程中处理,这点可以通过Handler传出来解决。
  2. 尝试Adapter的notifyDataSetChanged()方法,当然主要看你代码的具体情况。
  3. ActivityGroup对子A的管理是通过Map的方式来管理的,在启动子Activity时,对每个子Activity都分配了一个ID号。这种映射的机制使得我们可以通过ID来获取到子A的实例。当遇到
    <span style="font-size:16px">AlertDialog.Builder builder = new Builder(this);</span>
    不显示对话框时,使用
    <span style="font-size:16px">AlertDialog.Builder builder = new Builder(this.getParent());</span>
    代替,有可能会解决问题。
  4. Activity、Service实例化时就是一个Loop线程,同时具有本身的MessageQueue,因此可以在其内部定义
    <span style="font-size:16px">Handler handler = new Handler();</span>

  5. 代码中特殊的注释技术——TODO、FIXME和XXX的用处
    TODO: + 说明

    如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会简略说明。
    FIXME: + 说明
    如果代码中有该标识,说明识处代码需要修正,甚至代码是错误的,不能工作,需要修复,如何修正会在说明中简略说明。
    XXX: + 说明
    如果代码中有该标识,说明识处代码虽然实现了功能,但是实现的方法有待商榷,希望将来能改进,要改进的地方会在说明中简略说明。
  6. Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
  7. 非常惭愧,现在才发现try{}catch(Exception e){e.printStackTrace();},catch到Exception之后的代码还有可能执行。
  8. padding是控件内部的距离
    margin是控件间的距离
    <Button android:text="hello"
      android:layout_width="250dip"
     android:layout_height="100dip"
     android:paddingTop="50dip"    字体距离button上边距50dip
     android:layout_marginTop="100dip">     控件距离上一个控件100dip
    </Button>
  9. // 当向listview中加入headerview或者footviwer时,调用ListView的setAdapter
    // 方法会将adapter转化为headerviewlistadapter
    HeaderViewListAdapter listAdapter = (HeaderViewListAdapter) listView.getAdapter();
    ((BlogStatusAdapter) listAdapter.getWrappedAdapter()).refresh(refreshAlls);
  10. /** 将中文设置成粗体 ,英文直接使用android:textStyle="blod"即可*/
    TextPaint tp = mTextView.getPaint();
    tp.setFakeBoldText(true);
    SDK中这样描述的:
    TextPaint is an extension of Paint that leaves room for some extra data used during text measuring and drawing.
    绘画出文字时添加一些额外的信息
  11. 增加ImageView控件时会显示黄色的下划线,出现Missing contentDescription attribute on image的问题
    主要是因为在没有使用TextView之类的文本控件,这里添加 android:contentDescription="@string/app_name即可
  12. 有时候LinearLayout无法实现的布局,对于RelativeLayout来说迎刃而解。慎用LinearLayout,多用RelativeLayout。
  13. 可以把fragment看做是一个自定义的控件,这个控件包含了所有的界面和有关的操作后台代码。加载fragment有两种方式,第一种是直接在xml当中定义,第二种是在代码中使用事物操作加载到ViewGroup当中。
  14. 计算机程序是通过在计算机内存中开辟一块存储空间,并用一个语句序列不断修改这块存储空间上的内容,最终得到问题的解答来解决实际问题的。计算机程序一般需要用一种具体的程序设计语言表达出来。一种计算机语言通过定义变量的形式给出了申请内存的方式,并通过表达式和赋值语句给出了对内存中的数据进行运算和修改的方法。通过分支和循环语句提供了用不同方式安排语句序列的能力。大部分计算机语言还提供了基础函数库完成一些常用的计算和数据处理的功能。
    使用计算机程序解决实际问题,首先要能够将一个具体问题抽象成一个可计算的问题,并找出可行的计算过程;其次是掌握一门程序设计语言,将设计的计算过程写成具体的代码在机器上运行。
  15. C语言中scanf的第一个输入项为%c时,主要前面的输入中“\n”也会代替其输入,因此要在前加上 scanf("%c");以屏蔽之前的输入。
  16. #include <stdio.h>
    int main()
    {
        int x,n;
        printf("请输入数字:x n\n");
        scanf("%d %d",&x,&n);
        printf("x/n 向上取整的结果:%d\n",(x+n-1)/n);//整数向上取整
        return 0;
    }
  17. 左移一位相当于该数乘以2,左移2位相当于该数乘以2^2=4。上面举的例子15<< 2=60,即乘了4。但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。
  18. 全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) 。GUID是一种由算法生成的二进制长度为128位的数字标识符。GUID 的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个 x 是 0-9 或 a-f 范围内的一个32位十六进制数。例如:6F9619FF-8B86-D011-B42D-00C04FC964FF 即为有效的 GUID 值。
  19. Join,等待该线程终止,也就是等待该方法的线程执行完毕后再往下继续执行。注意该方法也需要捕捉异常。threadA.join.就是说,等待threadA执行完之后,剩下的线程再执行。有同步功能。 采用Thread.join()或CountDownLatch来实现线程间同步
  20. Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。Condition接口定义的方法,await()对应于Object#wait(),signal()对应于Object#notify(),signalAll()对应于Object#notifyAll()。Condition是与Lock结合使用的,通过Lock.newCondition()方法能够创建与Lock绑定的Condition实例。Lock和Condition的关系就如同synchronized方法和Object.wait(),Object.notify()一样,它们都可以配合使用完成对多线程协作的控制。 
  21. ThreadPoolExecutor进行线程复用的关键代码(JDK7中)
     final void runWorker(Worker w) {
            Thread wt = Thread.currentThread();
            Runnable task = w.firstTask;
            w.firstTask = null;
            w.unlock(); // allow interrupts
            boolean completedAbruptly = true;
            try {
                while (task != null || (task = getTask()) != null) {
                    w.lock();
                    // If pool is stopping, ensure thread is interrupted;
                    // if not, ensure thread is not interrupted.  This
                    // requires a recheck in second case to deal with
                    // shutdownNow race while clearing interrupt
                    if ((runStateAtLeast(ctl.get(), STOP) ||
                         (Thread.interrupted() &&
                          runStateAtLeast(ctl.get(), STOP))) &&
                        !wt.isInterrupted())
                        wt.interrupt();
                    try {
                        beforeExecute(wt, task);
                        Throwable thrown = null;
                        try {
                            task.run();
                        } catch (RuntimeException x) {
                            thrown = x; throw x;
                        } catch (Error x) {
                            thrown = x; throw x;
                        } catch (Throwable x) {
                            thrown = x; throw new Error(x);
                        } finally {
                            afterExecute(task, thrown);
                        }
                    } finally {
                        task = null;
                        w.completedTasks++;
                        w.unlock();
                    }
                }
                completedAbruptly = false;
            } finally {
                processWorkerExit(w, completedAbruptly);
            }
        }
    以上代码中
    while (task != null || (task = getTask()) != null) {
    不断从任务队列BlockingQueue中取任务,取任务的时间设置为keepAliveTime,这样整个Thread的声明周期就被动的增加了keepAliveTime时间,如果在这个时间里取到了新的任务,那么将执行
    task.run();
    run()方法不同于start()方法,其不会开启新的线程,会复用之前的线程,这要就实现了线程的复用操作。
    其中worker是整个ThreadPoolExecutor的关键。
     Worker(Runnable firstTask) {
                setState(-1); // inhibit interrupts until runWorker
                this.firstTask = firstTask;
                this.thread = getThreadFactory().newThread(this);
            }
    说明了其新建的线程thread为Runnable的运行线程,同时run方法用了代理模式,对原任务的run方法包装
      public void run() {
                runWorker(this);
            }
    
    其他主要集合分别为
    private final BlockingQueue<Runnable> workQueue;
    用于存放待运行的任务,而
    private final HashSet<Worker> workers = new HashSet<Worker>();
    用于存放正在运行的任务。
  22. Future<V>、FutureTask<V>、Callable<V>、Runnable;其中Future<V>接口用于对线程的状态,等待、运行和完成进行监控。而FutureTask<V>实现了这个接口,同时其实现了Callable<V>、Runnable,这样,就可以对Callable<V>、Runnable的实现线程进行状态的监控。
  23. Semaphore是Java下的信号量,与Linux平台下的信号量类似。Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
    Java中Semaphore的构造中带有一个fairness的参数,用于设置是否“公平”。当fairness为true时,Semaphore保证各线程以后进先出(FIFO)的方式获得信号量。如果fairness为false,则不保证这种顺序,允许各线程之间的“讨价还价”。
  24. LinkedHashMap的构造函数中三个参数的含义:initialCapacity: hashMap初始化时,创建的Hash桶数目
    loadFactor: 当已经被使用的Hash桶数目达到总数*loadFactor,需要进行扩容,容量变成之前的2倍
    accessOrder:LRU在这里体现,当这个值为true的时候,使用的就是LRU算法,也就是最近访问的放在最前面,最近少访问的放在后面。具体实现办法是,当使用get()方法获取一个值后,会把这个值所在的hash桶放在所有桶的最前面,这样下次访问可以最快取得
  25. Eclipse的SVN插件http://subclipse.tigris.org/
  26. 解决更新SDK的问题,将C:\Windows\System32\drivers\etc\hosts文件增加一下两行,
    203.208.46.146 dl.google.com
    203.208.46.146 dl-ssl.google.com
  27. 一个对象可以从某个角度上分为有状态对象和无状态对象,而区分的标准就是对象是否具备代表其自身属性的字段。
  28. JNI或者NDK生成头文件命令:
    javah -classpath "C:\android-sdk-windows\platforms\android-14\android.jar;bin/classes" -d jni com.example.hellojni.HelloJni

  29. jQuery也可以用$来代替。
    根据div的id获取对象:
    1.jQuery("#divs"):id用"#"
    2.$("#divs")
    根据class获取对象:
    1.jQuery(".clsdiv"):class用"."
    2.$(".clsdiv")
  30. Windows7下Eclipse字体偏小的解决方案:1. 用WinRAR找到并打开org.eclipse.jface_3.7.0.I20110522-1430.jar
    具体位置在$Eclipse目录$/plugins/org.eclipse.jface_3.7.0.I20110522-1430.jar
    2.找到并修改字体属性
    依次展开org/eclipse/jface/resources,找到jfacefonts_windows7.properties,用一个文本编译器打开,找到org.eclipse.jface.textfont.0的配置项,将其设置成Courier New-regular-10即可,后面还可以设置字号。修改完成后,保存,WinRAR自动更新jar包。
  31. 返回并刷新 
     <script>alert("恭喜您,操作成功!"); window.location.href=document.referrer; </script>
    返回不刷新
    <script>alert("恭喜您,操作成功!"); window.history.back(-1); </script>
  32. CyclicBarrier一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。 

    CountDownLatch: 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。   
    CyclicBarrier: N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
    这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。
    CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.而CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.
    CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用。
  33. 定义成volatile的变量,能够在线程之间保持可见性,能够被多线程同时读,并且保证不会读到过期的值,但是只能被单线程写(有一种情况可以被多线程写,就是写入的值不依赖于原值),在get操作里只需要读不需要写共享变量count和value,所以可以不用加锁。之所以不会读到过期的值,是根据java内存模型的happen before原则,对volatile字段的写入操作先于读操作,即使两个线程同时修改和获取volatile变量,get操作也能拿到最新的值,这是用volatile替换锁的经典应用场景。
  34. Redis 模糊删除字段如删除已“#USERGROUP_GROUPID_KEY#”开头的字段,则在Redis的src文件夹下,使用./redis-cli keys "#USERGROUP_GROUPID_KEY#*" | xargs ./redis-cli del
  35. select * from mytable inner join (select id from mytable order by id asc limit 900000, 10 ) as temp using(id);//limit优化1
    Select * From mytable Where id >=(Select id From mytable Order By id limit 900000,1) limit 10;//limit优化2


  36. % 代表针对被编辑文件的每一行进行后续操作$ 代表一行的结尾处^ 代表一行的开头处除了直接用 A 以外,你也可以按了 $ 之后用小写的 ai 在光标之前, a 在光标之后,你行尾属于光标之后添加,应该用 a
  37. <%%>是jspscript代码段,在由jsp转换成Servlet后 <%%>中的代码是放在serive方法中,相当与  
         doGet()和doPost()方法
    <%!%>是jsp声明,用来定义属性和方法的,在由jsp转换成Servlet后 <%!%>中的代码是放serive  
         方法之外的
    <%=%>是jsp表达式,在由jsp转换成Servlet后 <%=%>中的代码是放在,service方法中的
           out.println("这里")中的其中的内容将直接输出到浏览器的页面中
  38. 记录一个nginx服务器问题,ping能够ping通,但是就是访问不了nginx下的页面,telent ip 80 发现无法成功,于是考虑是不是linux防火墙问题,在使用service iptables stop 关闭防火墙之后,能够正常访问应用!
  39. java registerNatives() 方法的作用,如果不覆写Object的话,一般为了使JVM能够找到本地方法,需要按照一定的命名规则命名本地方法。比如,java.lang.Object.registerNatives对应的C函数叫做 Java_java_lang_Object_registerNatives,为了是的编程人员可以自由的命名本地函数,进而提供了registerNatives这个函数,这个绑定的工作有registerNatives来完成。What does the registerNatives() method do?  
    #include <stdio.h>
    #include <signal.h>
    #include <limits.h>
    
    #include "jni.h"
    #include "jni_util.h"
    #include "jvm.h"
    
    #include "java_lang_Object.h"
    
    static JNINativeMethod methods[] = {
        {"hashCode",    "()I",                    (void *)&JVM_IHashCode},
        {"wait",        "(J)V",                   (void *)&JVM_MonitorWait},
        {"notify",      "()V",                    (void *)&JVM_MonitorNotify},
        {"notifyAll",   "()V",                    (void *)&JVM_MonitorNotifyAll},
        {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
    };
    
    JNIEXPORT void JNICALL
    Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
    {
        (*env)->RegisterNatives(env, cls,
                                methods, sizeof(methods)/sizeof(methods[0]));
    }
    
    JNIEXPORT jclass JNICALL
    Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
    {
        if (this == NULL) {
            JNU_ThrowNullPointerException(env, NULL);
            return 0;
        } else {
            return (*env)->GetObjectClass(env, this);
        }
    }

  40. new Thread的时候,首先会调用JVM_CurrentThread()注册本地方法,另外就是Thread的构造方法会调用init方法,init方法,会调用currentThread本地方法,这个方法会新建一个本地线程同时拿到这个thread引用(句柄),同时init方法会设置线程的group,daemon,priority,name,contextClassLoader同时创建ThreadLoacalMap,此时的thread是new状态,当调用start方法时,thread状态时runnable状态。

你可能感兴趣的:([置顶] 开发总结)