我正在每天动态地使用以下位图图像上的指定绘画来绘制具有指定开始和结束 x,y 坐标的线段 -
chart_by_rule (>= 4.4 中出现意外) -
chart_by_rule (预期) -
以下代码应在上面的位图中绘制线条。这些线条仅在 Android 版本 < 4.4 中绘制。
这是代码-
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
{
getActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
getChartLoaded();
}
});
}
public void getChartLoaded()
{
if(dates_array.indexOf(today) == -1 || (redrawChart != null && redrawChart.equals("popback")) || (getSetting("ZoneIDChanged","0").equals("1")))
{
redrawChartView(scal, zeroPadding, zeroPaddingDate);
setSetting("ZoneIDChanged","0");
}
else
{
addChartViews(scal, zeroPadding, zeroPaddingDate);
}
}
public void redrawChartView(Calendar scal,
String zeroPadding, String zeroPaddingDate)
{
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(driverTimeZone));
while (scal.compareTo(cal) < 0) {
cv = new ChartView();
LinearLayout layout = cv.getChartView(i);
i++;
linearLayoutMap.put(date, layout);
views.add(layout);
}
}
public class ChartView
{
private Paint cPaint;
float startHours = 0, endHours = 0,
startHeight = 0, endHeight = 0,
scale = 0;
public LinearLayout getChartView(final int number)
{
getActivity().runOnUiThread(new Runnable()
{
@Override
public void run() {
cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
cPaint.setStyle(Paint.Style.STROKE);
cPaint.setColor(Color.BLACK);
cPaint.setStrokeWidth(3);
scale = getActivity().getBaseContext().getResources()
.getDisplayMetrics().density;
linearlayout = new LinearLayout(getActivity());
final ImageView img = new ImageView(getActivity());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
newBitmap = BitmapFactory.decodeResource(getResources(),
chart_by_rule).copy(Bitmap.Config.ARGB_4444, true);
canvas = new Canvas(newBitmap);
img.setImageBitmap(newBitmap);
img.setScaleType(ScaleType.FIT_XY);
img.setTag(number);
float wFactor = (15 * scale);
float hFactor = (float) ((19.35) * scale);
float x1 = startHours * wFactor;
float x2 = endHours * wFactor;
float y1 = (2 * startHeight - 1) * hFactor;
float y2 = (2 * endHeight - 1) * hFactor;
canvas.drawLine(x1, y1, x2, y2, cPaint);
canvas.save(Canvas.ALL_SAVE_FLAG);
linearlayout.addView(img);
}
});
return linearlayout;
}
}
This code is working fine in all the android versions smaller then 4.4.
在 Android OS >= 4.4
中,我在包含 ImageView 的线性布局上没有使用 Canvas 绘制任何线条。
这些更高版本的操作系统在 Canvas 方面是否有任何变化,或者问题可能出在其他地方?
更多:我对所有屏幕布局都有不同的布局文件。
已使用Motorola XT907
对此进行检查。
这是手机规范 - http://wiki.cyanogenmod.org/w/Xt907_Info .
最佳答案
这是与DiskLruCache相关的问题缓存页面。
注意:您创建实例的位置很重要。
DiskLruCache
基于磁盘的 LRU 缓存的 Java 实现,专门针对 Android 兼容性。
DiskLruCache
文档提到,
This class is tolerant of some I/O errors. If files are missing from the filesystem, the corresponding entries will be dropped from the cache. If an error occurs while writing a cache value, the edit will fail silently. Callers should handle other problems by catching IOException and responding appropriately.
解决方案:
我有 -
final int DISK_CACHE_SIZE = 1024 * 1024 * memClass / 10;
cache = new DiskLruImageCache(getActivity(), DISK_CACHE_SUBDIR,
DISK_CACHE_SIZE, CompressFormat.JPEG, 100);
其中,DiskLruImageCache是一个类。
此缓存实例代码位于 fragment 的 onCreate()
方法中。
删除了onCreate()
中的代码并将其放在fragment的onCreateView()
方法中。
现在 android 4.4 及更高版本也显示带有绘制线的位图。
这很奇怪,但似乎在这方面发生了一些变化,导致了这样的问题。
重用位图
然后我在whats-changed-in-android-4-4-kitkat找到了重用位图的文章.
如上所述,
包含Bitmap.reconfigure()
用于修改现有实例以适应新的尺寸和像素配置。 BitmapFactory
也已更新,以便在 Bitmap 中重用此重新配置行为。
您可以安全地将实例从 ARGB_8888
处的 200×200
重新配置为 ARGB_8888
处的 100×100
,然后再次到 RGB_565
处的 300×300
,因为所有这些都适合初始分配。但是,如果我尝试在 ARGB_8888
将其重新配置为 300×300
,则会引发异常。还需要注意的是,当位图附加到 View 时,您无法重新配置位图。这应该在元素被分离或移出屏幕后完成。
因此,如果您的应用程序可以为单个实例确定合适的大小,即使它可能大于任何给定时间所需的像素,您仍然可以减少内存使用量。对于每个人来说,对 300×300
和 200×200
图像(显然不会同时显示)重复使用的单个 360KB
位图比需要520KB (360KB + 160KB)
对于两个单独的实例。
我希望以后可能遇到此问题的任何人都能从这里获得帮助。
关于android - 在高于 4.4 的 Android 操作系统版本中,无法使用 Canvas 绘制线条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25075859/