android - 在高于 4.4 的 Android 操作系统版本中,无法使用 Canvas 绘制线条

标签 android android-canvas android-version

我正在每天动态地使用以下位图图像上的指定绘画来绘制具有指定开始和结束 x,y 坐标的线段 -

chart_by_rule (>= 4.4 中出现意外) -

enter image description here

chart_by_rule (预期) -

enter image description here

以下代码应在上面的位图中绘制线条。这些线条仅在 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×300200×200 图像(显然不会同时显示)重复使用的单个 360KB 位图比需要520KB (360KB + 160KB) 对于两个单独的实例。

我希望以后可能遇到此问题的任何人都能从这里获得帮助。

关于android - 在高于 4.4 的 Android 操作系统版本中,无法使用 Canvas 绘制线条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25075859/

相关文章:

android - Gradle Android 找不到方法 testPackage()

android - 为什么在向应用程序提供数据时 View 会分散在应用程序中?

java - Android Canvas 循环绘制矩形

java - Canvas 如何确定其裁剪范围?

android - 如何找到官方的android studio旧版本

java - Android 运行时权限(权限被拒绝)

java - 获取两点之间的距离并计算出速度

用于 2d 游戏的 Android Canvas 或 Open GL ES?

android - 哪些安卓操作系统版本支持 "Do Not Disturb"设置?