SurfaceView و GLSurfaceView

رابط کاربر چارچوب برنامه Android بر اساس سلسله مراتبی از اشیا that است که با View شروع می شوند. همه عناصر UI از یک سری اندازه گیری ها و یک فرایند چیدمان برخوردارند که آنها را در یک ناحیه مستطیل قرار می دهد. سپس ، تمام اشیا view نمای قابل مشاهده به سطحی ارائه می شوند که هنگام معرفی برنامه به پیش زمینه توسط WindowManager تنظیم شده است. موضوع UI برنامه چیدمان و ارائه را به یک بافر در هر فریم انجام می دهد.

SurfaceView

SurfaceView م componentلفه ای است که می توانید از آن برای قرار دادن یک لایه ترکیبی اضافی در سلسله مراتب نمای خود استفاده کنید. یک SurfaceView همان پارامترهای چیدمان سایر نماها را دارد ، بنابراین می توان مانند هر نمای دیگر آن را دستکاری کرد ، اما محتوای SurfaceView شفاف است.

هنگامی که با یک منبع بافر خارجی ، مانند GLtext یا یک رمزگشای رسانه رندر می کنید ، باید بافرها را از منبع بافر کپی کنید تا بافرها روی صفحه نمایش داده شوند. استفاده از SurfaceView شما را قادر به انجام چنین کاری می کند.

هنگامی که م componentلفه نمای SurfaceView در معرض دید قرار دارد ، این چارچوب از SurfaceControl می خواهد سطح جدیدی را از SurfaceFlinger درخواست کند. برای دریافت برگشت تماس هنگام ایجاد یا تخریب سطح ، از رابط SurfaceHolder استفاده کنید. به طور پیش فرض ، سطح تازه ایجاد شده در پشت سطح UI برنامه قرار می گیرد. برای قرار دادن سطح جدید در بالای صفحه می توانید ترتیب پیش فرض Z را نادیده بگیرید.

رندر با SurfaceView در مواردی که نیاز به ارائه به یک سطح جداگانه دارید ، مفید است ، مانند زمانی که با Camera API یا زمینه OpenGL ES رندر می کنید. هنگامی که با SurfaceView رندر می کنید ، SurfaceFlinger مستقیماً بافرها را روی صفحه ترکیب می کند. بدون SurfaceView ، باید بافرها را به یک سطح خارج از صفحه بسپارید ، سپس به صفحه کامپوزیت می شود ، بنابراین ارائه با SurfaceView کار اضافی را از بین می برد. پس از ارائه با SurfaceView ، از نخ UI استفاده کنید تا با چرخه حیات فعالیت هماهنگ شود و در صورت نیاز ، اندازه یا موقعیت نمای را تنظیم کنید. سپس ، Hardware Composer برنامه UI و لایه های دیگر را با هم مخلوط می کند.

سطح جدید سمت تولید کننده BufferQueue است که مصرف کننده آن یک لایه SurfaceFlinger است. شما می توانید با هر مکانیزمی که می تواند BufferQueue را تغذیه کند ، سطح را به روز کنید ، مانند عملکردهای Canvas ، تهیه سطح ، اتصال EGLSurface و نقاشی روی سطح با GLES یا پیکربندی یک رمزگشای رسانه برای نوشتن سطح.

SurfaceView و چرخه عمر فعالیت

هنگام استفاده از SurfaceView ، سطح را از موضوعی غیر از موضوع اصلی UI ارائه دهید.

برای فعالیت با SurfaceView ، دو ماشین حالت جداگانه اما به هم وابسته وجود دارد:

  • برنامه onCreate / onResume / onPause
  • سطح ایجاد / تغییر / تخریب شده است

وقتی فعالیت شروع می شود ، با این ترتیب پاسخ می گیرید:

  1. onCreate()
  2. onResume()
  3. surfaceCreated()
  4. surfaceChanged()

اگر دوباره کلیک کنید ، دریافت خواهید کرد:

  1. onPause()
  2. surfaceDestroyed() (درست قبل از اینکه سطح از بین برود نامیده می شود)

اگر صفحه را بچرخانید ، فعالیت متلاشی شده و دوباره ایجاد می شود و چرخه کامل را بدست می آورید. با بررسی isFinishing() می توانید بگویید که شروع مجدد سریع است. شروع / توقف فعالیتی به سرعت امکان پذیر است که surfaceCreated() بعد از onPause() اتفاق می افتد.

اگر روی دکمه روشن / خاموش ضربه بزنید تا صفحه خالی شود ، فقط onPause() بدون surfaceDestroyed() . سطح فعال باقی مانده و ارائه می تواند ادامه یابد. اگر به درخواست های Choreographer ادامه دهید ، می توانید به آنها ادامه دهید. اگر صفحه قفل دارید که جهت دیگری را تحمیل می کند ، ممکن است با باز نشدن دستگاه ، فعالیت شما دوباره شروع شود. در غیر این صورت ، می توانید از صفحه خالی با همان سطح قبلی بیرون بیایید.

طول عمر نخ می تواند به سطح یا فعالیت گره بخورد ، بسته به آنچه می خواهید هنگام خالی شدن صفحه اتفاق بیفتد. رشته می تواند یا در شروع / توقف فعالیت یا در ایجاد یا تخریب سطح شروع یا متوقف شود.

داشتن / شروع و توقف موضوع در شروع / توقف فعالیت با چرخه عمر برنامه به خوبی کار می کند. شما رشته رندر را در onResume() و آن را در onResume() متوقف کنید onStop() . هنگام ایجاد و پیکربندی موضوع ، گاهی اوقات سطح از قبل وجود دارد ، در اکثر مواقع وجود ندارد (به عنوان مثال ، پس از تغییر وضعیت صفحه با دکمه روشن / خاموش) هنوز فعال است. قبل از مقداردهی اولیه در نخ باید منتظر ایجاد سطح باشید. شما نمی توانید مقداردهی اولیه را در سطح سطح ایجاد کنید surfaceCreate() زیرا در صورت عدم ایجاد مجدد سطح ، دوباره آتش نمی گیرد. درعوض ، سطح سطح را پرس وجو کرده یا حافظه پنهان کرده و آن را به رشته رندر ارسال کنید.

داشتن نخ شروع یا توقف روی سطح ایجاد / از بین بردن به خوبی کار می کند زیرا سطح و رندر به طور منطقی در هم آمیخته اند. پس از ایجاد سطح ، نخ را شروع می کنید ، که از برخی نگرانی های ارتباط بین رشته جلوگیری می کند. و پیامهای ایجاد شده یا تغییر یافته به سادگی ارسال می شوند. برای اطمینان از اینکه هنگام خالی ماندن صفحه رندر متوقف می شود و در صورت لغو خالی شدن صفحه از سر گرفته می شود ، به Choreographer بگویید که از فراخوانی پاسخ ترسیم قاب جلوگیری کند. onResume() از سر گرفته از تماس اگر موضوع رندر در حال اجرا است. با این حال ، اگر براساس زمان سپری شده بین فریم ها انیمیشن انجام دهید ، ممکن است قبل از رسیدن رویداد بعدی ، فاصله زیادی وجود داشته باشد. با استفاده از پیام مکث / رزومه صریح می توانید این مسئله را حل کنید.

هر دو گزینه ، خواه طول عمر نخ به Activity یا سطح آن گره خورده باشد ، بر نحوه پیکربندی موضوع رندر و اجرای آن متمرکز هستند. نگرانی مربوط به استخراج حالت از موضوع هنگام از بین رفتن فعالیت است (در onStop() یا onSaveInstanceState() ). در چنین مواردی ، اتصال طول موضوع به فعالیت به بهترین وجهی جواب می دهد زیرا پس از اتصال رشته رندر ، می توان به حالت رشته ارائه شده بدون ابتدای همگام سازی دسترسی داشت.

GLSurfaceView

کلاس GLSurfaceView کلاس های کمکی را برای مدیریت زمینه های EGL ، ارتباط بین رشته ای و تعامل با چرخه حیات فعالیت فراهم می کند. برای استفاده از GLES نیازی به استفاده از GLSurfaceView ندارید.

به عنوان مثال ، GLSurfaceView یک رشته برای رندر ایجاد می کند و زمینه EGL را در آنجا پیکربندی می کند. با توقف فعالیت ، حالت به طور خودکار پاک می شود. برای استفاده از GLES با GLSurfaceView ، اکثر برنامه ها نیازی به دانستن چیزی در مورد EGL ندارند.

در بیشتر موارد ، GLSurfaceView می تواند کار با GLES را آسان کند. در برخی شرایط می تواند مانع شود.