안드로이드 성능 최적화는 SparseArray를 사용하여 2013년 08월 01일android가 최근에 원 프로젝트를 재구성하였는데, 그 중에서HashMap으로ActivityGroup 불러오기를 캐시합니다
Use new SparseArray<View> (...) instead for better performance
더 나은 성능을 얻기 위해 SparseArray로 대체한다는 뜻이다.SparseArray에 대해 전혀 익숙하지 않고 심지어 들어보지도 못했다. 첫 번째 느낌은 안드로이드가 제공하는 클래스일 것이다. 그래서 F3가 SparseArray의 원본에 들어갔는데 아니나 다를까 안드로이드가 제공하는 도구 클래스였다. 일부 원본은 다음과 같다.
* Copyright (C) 2006 The Android Open Source Project
*
* 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.
*/
package android.util;
import com.android.internal.util.ArrayUtils;
/**
* SparseArrays map integers to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more efficient
* than using a HashMap to map Integers to Objects.
*/
public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
private boolean mGarbage = false;
private int[] mKeys;
private Object[] mValues;
private int mSize;
/**
* Creates a new SparseArray containing no mappings.
*/
public SparseArray() {
this(10);
}
/**
* Creates a new SparseArray containing no mappings that will not
* require any additional memory allocation to store the specified
* number of mappings.
*/
public SparseArray(int initialCapacity) {
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
mKeys = new int[initialCapacity];
mValues = new Object[initialCapacity];
mSize = 0;
}
@Override
@SuppressWarnings("unchecked")
public SparseArray<E> clone() {
SparseArray<E> clone = null;
try {
clone = (SparseArray<E>) super.clone();
clone.mKeys = mKeys.clone();
clone.mValues = mValues.clone();
} catch (CloneNotSupportedException cnse) {
/* ignore */
}
return clone;
}
/**
* Gets the Object mapped from the specified key, or <code>null</code>
* if no such mapping has been made.
*/
public E get(int key) {
return get(key, null);
}
/**
* Gets the Object mapped from the specified key, or the specified Object
* if no such mapping has been made.
*/
@SuppressWarnings("unchecked")
public E get(int key, E valueIfKeyNotFound) {
int i = binarySearch(mKeys, 0, mSize, key);
if (i < 0 || mValues[i] == DELETED) {
return valueIfKeyNotFound;
} else {
return (E) mValues[i];
}
}
/**
* Removes the mapping from the specified key, if there was any.
*/
public void delete(int key) {
int i = binarySearch(mKeys, 0, mSize, key);
if (i >= 0) {
if (mValues[i] != DELETED) {
mValues[i] = DELETED;
mGarbage = true;
}
}
}
/**
* Alias for {@link #delete(int)}.
*/
public void remove(int key) {
delete(key);
}
/**
* Removes the mapping at the specified index.
*/
public void removeAt(int index) {
if (mValues[index] != DELETED) {
mValues[index] = DELETED;
mGarbage = true;
}
}
...
mSize++; ,SparseArray (Sparse array), ( ), 。 , , , 。
계속해서 SparseArray의 원본 코드를 읽습니다. 구성 방법을 보면 일반적인 List와 마찬가지로 용기 크기를 미리 설정할 수 있습니다. 기본 크기는 10입니다.
public SparseArray() {
this(10);
}
public SparseArray(int initialCapacity) {
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
mKeys = new int[initialCapacity];
mValues = new Object[initialCapacity];
mSize = 0;
}
데이터에 대한 추가 삭제와 수정을 다시 한 번 봅시다.
public void put(int key, E value) {}
public void append(int key, E value){}
수정 데이터는 처음에 setValueAt(int index, E value)만 수정할 수 있다고 생각했지만put(int key, E value)도 데이터를 수정할 수 있는 것으로 알았습니다.put(int key, E value)의 원본 코드를 보면 put 데이터가 존재하는지 확인하고put 데이터가 존재하지 않으면 추가하는 것을 알 수 있습니다.
public void put(int key, E value) {
int i = binarySearch(mKeys, 0, mSize, key);
if (i >= 0) {
mValues[i] = value;
} else {
i = ~i;
if (i < mSize && mValues[i] == DELETED) {
mKeys[i] = key;
mValues[i] = value;
return;
}
if (mGarbage && mSize >= mKeys.length) {
gc();
// Search again because indices may have changed.
i = ~binarySearch(mKeys, 0, mSize, key);
}
if (mSize >= mKeys.length) {
int n = ArrayUtils.idealIntArraySize(mSize + 1);
int[] nkeys = new int[n];
Object[] nvalues = new Object[n];
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
mKeys = nkeys;
mValues = nvalues;
}
if (mSize - i != 0) {
// Log.e("SparseArray", "move " + (mSize - i));
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
}
mKeys[i] = key;
mValues[i] = value;
}
}
따라서 데이터를 수정하는 방법에는 실제로 두 가지가 있습니다.
public void put(int key, E value)
public void setValueAt(int index, E value)
마지막으로 데이터를 어떻게 찾는지 다시 봅시다.두 가지 방법으로 값을 질의할 수 있습니다.
public E get(int key)
public E get(int key, E valueIfKeyNotFound)
그 중에서 get (int key) 도 get (int key, E value If Key Not Found) 을 호출했을 뿐, 마지막으로 인용된 변수 이름에서 알 수 있듯이, 전송된 값은 찾을 수 없을 때 되돌아오는 값이다.get (int key) 을 찾을 수 없을 때 기본값으로null을 되돌려줍니다.
몇 번째 위치의 키를 보려면 다음과 같이 하십시오.
public int keyAt(int index)
한 가지 주의해야 할 것은 키가 있는 위치를 확인하는 것이다. 이분법으로 키의 위치를 찾기 때문에 0보다 작은 수치를 찾을 수 없고 -1을 되돌릴 수 없다.되돌아오는 마이너스는 그것이 찾을 수 없는 위치를 표시하는 것이다.
몇 번째 위치의 값을 보려면 다음과 같이 하십시오.
public E valueAt(int index)
값이 있는 위치를 보고 없으면 -1을 반환합니다.
public int indexOfValue(E value)
마지막으로 그 핵심은 반절 검색 함수(binary Search)라는 것을 발견했고 알고리즘은 잘 설계되었다.
private static int binarySearch(int[] a, int start, int len, int key) {
int high = start + len, low = start - 1, guess;
while (high - low > 1) {
guess = (high + low) / 2;
if (a[guess] < key)
low = guess;
else
high = guess;
}
if (high == start + len)
return ~(start + len);
else if (a[high] == key)
return high;
else
return ~high;
}
SparseBooleanArray, HashMap<Integer, Boolean>,SparseIntArray HashMap<Integer, Integer>, 。
총결산
SparseArray android <Interger,Object> Hashmap , , (binarySearch)。 Android ,
HashMap<Integer, E> hashMap = new HashMap<Integer, E>();
, .
SparseArray<E> sparseArray = new SparseArray<E>();
마지막으로 재구성된 Activity GroupManager를 살펴보겠습니다.
public class ActivityGroupManager {
static final String TAG = ActivityGroupManager.class.getName();
private SparseArray<View> array;
private ViewGroup container;
public ActivityGroupManager() {
array = new SparseArray<View>();
}
public void setContainer(ViewGroup container) {
this.container = container;
}
public void showContainer(int num, View view) {
if (array.get(num) == null) {
array.put(num, view);
container.addView(view);
}
for (int i = 0; i < array.size(); i++) {
View v = array.valueAt(i);
v.setVisibility(View.GONE);
}
view.setVisibility(View.VISIBLE);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.