{"id":2422,"date":"2026-04-28T08:11:42","date_gmt":"2026-04-28T16:11:42","guid":{"rendered":"https:\/\/www.yoonhuh.com\/blog\/?p=2422"},"modified":"2026-04-28T08:16:47","modified_gmt":"2026-04-28T16:16:47","slug":"hxaudioplayer-4-0-0-released","status":"publish","type":"post","link":"https:\/\/www.yoonhuh.com\/blog\/hxaudioplayer-4-0-0-released\/","title":{"rendered":"HXAudioPlayer 4.0.0 Released"},"content":{"rendered":"<p data-start=\"129\" data-end=\"254\">I\u2019m excited to announce the release of <strong data-start=\"168\" data-end=\"191\">HXAudioPlayer 4.0.0<\/strong>, the latest major update to this Android audio playback library.<\/p>\n<p data-start=\"256\" data-end=\"670\"><strong data-start=\"256\" data-end=\"273\">HXAudioPlayer<\/strong> is an Android library designed to make audio playback easier to implement by wrapping Android\u2019s <code data-start=\"370\" data-end=\"383\">MediaPlayer<\/code> and <code data-start=\"388\" data-end=\"399\">SoundPool<\/code> APIs behind a simpler interface. It was originally built for games and game-oriented Android apps, where apps often need to manage both background music and short sound effects without manually handling the complexity of multiple <code data-start=\"630\" data-end=\"643\">MediaPlayer<\/code> and <code data-start=\"648\" data-end=\"659\">SoundPool<\/code> instances.<\/p>\n<p data-start=\"672\" data-end=\"980\">The library provides a straightforward way to play, pause, resume, loop, and manage music and sound effects with less boilerplate. It is currently used in several Y-Corner Android apps, including <strong data-start=\"868\" data-end=\"882\">Dragon Geo<\/strong>, <strong data-start=\"884\" data-end=\"906\">Cid\u2019s Aerial Views<\/strong>, <strong data-start=\"908\" data-end=\"923\">Chrono Maps<\/strong>, <strong data-start=\"925\" data-end=\"950\">Robot Master Database<\/strong>, and <strong data-start=\"956\" data-end=\"979\">Map of the Nocturne<\/strong>.<\/p>\n<p data-start=\"982\" data-end=\"1296\">Version <strong data-start=\"990\" data-end=\"999\">4.0.0<\/strong> is the first major update since <strong data-start=\"1032\" data-end=\"1042\">v3.3.1<\/strong>, which was last updated in <strong data-start=\"1070\" data-end=\"1082\">May 2018<\/strong>. This release modernizes the library for newer Android versions, adds full support for <strong data-start=\"1170\" data-end=\"1193\">Android 17 \/ API 37<\/strong>, and removes legacy compatibility support for <strong data-start=\"1240\" data-end=\"1252\">API 9\u201320<\/strong>, including Android 2.3 through Android 4.4.<\/p>\n<p data-start=\"1298\" data-end=\"1355\">The latest release and full changelog are available here: <a href=\"https:\/\/github.com\/huhx0015\/HXAudioPlayer\/releases\/tag\/v4.0.0\">https:\/\/github.com\/huhx0015\/HXAudioPlayer\/releases\/tag\/v4.0.0<\/a><\/p>\n<p>The HXAudioPlayer repository is available here: <a href=\"https:\/\/github.com\/huhx0015\/HXAudioPlayer\">https:\/\/github.com\/huhx0015\/HXAudioPlayer<\/a><\/p>\n<h2 data-section-id=\"ocw03s\" data-start=\"1541\" data-end=\"1585\">Migrating from HXAudioPlayer 3.x to 4.0.0<\/h2>\n<p data-start=\"1587\" data-end=\"1791\">HXAudioPlayer 4.0.0 is a major release that modernizes the library for current Android versions. Most existing music and sound playback APIs remain familiar, but there are a few important migration notes.<\/p>\n<h3 data-section-id=\"ra975a\" data-start=\"1793\" data-end=\"1823\">1. Minimum Android Version<\/h3>\n<p data-start=\"1825\" data-end=\"1896\">HXAudioPlayer now requires <strong data-start=\"1852\" data-end=\"1895\">Android 5.0 Lollipop \/ API 21 or higher<\/strong>.<\/p>\n<p data-start=\"1898\" data-end=\"1927\">Support has been removed for:<\/p>\n<ul data-start=\"1929\" data-end=\"2061\">\n<li data-section-id=\"19mfp3w\" data-start=\"1929\" data-end=\"1954\">Android 2.3 Gingerbread<\/li>\n<li data-section-id=\"o8v3og\" data-start=\"1955\" data-end=\"1978\">Android 3.x Honeycomb<\/li>\n<li data-section-id=\"1xxlvmr\" data-start=\"1979\" data-end=\"2011\">Android 4.0 Ice Cream Sandwich<\/li>\n<li data-section-id=\"1ib09to\" data-start=\"2012\" data-end=\"2040\">Android 4.1\u20134.3 Jelly Bean<\/li>\n<li data-section-id=\"16950et\" data-start=\"2041\" data-end=\"2061\">Android 4.4 KitKat<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p data-start=\"2063\" data-end=\"2170\">If your app still needs to support <strong data-start=\"2098\" data-end=\"2110\">API 9\u201320<\/strong>, you should remain on the latest HXAudioPlayer 3.x release.<\/p>\n<h3 data-section-id=\"1gbbwzr\" data-start=\"2172\" data-end=\"2200\">2. Remote Audio Playback<\/h3>\n<p data-start=\"2202\" data-end=\"2262\">For apps streaming audio from remote URLs, prefer <strong data-start=\"2252\" data-end=\"2261\">HTTPS<\/strong>.<\/p>\n<p data-start=\"2264\" data-end=\"2535\">Because modern Android target SDK behavior blocks cleartext traffic by default, <code data-start=\"2344\" data-end=\"2353\">http:\/\/<\/code> URLs may fail unless cleartext traffic is explicitly enabled. If HTTP is required, use a scoped <code data-start=\"2450\" data-end=\"2473\">networkSecurityConfig<\/code> when possible instead of enabling cleartext traffic globally.<\/p>\n<h3 data-section-id=\"ozsk\" data-start=\"2537\" data-end=\"2579\">3. Legacy SoundPool Compatibility APIs<\/h3>\n<p data-start=\"2581\" data-end=\"2671\">A few older compatibility APIs remain, but should no longer be relied on for normal usage:<\/p>\n<div class=\"relative w-full mt-4 mb-1\">\n<div class=\"\">\n<div class=\"relative\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"border border-token-border-light border-radius-3xl corner-superellipse\/1.1 rounded-3xl\">\n<div class=\"h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse\/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback\">\n<div class=\"relative\">\n<div class=\"\">\n<div class=\"relative z-0 flex max-w-full\">\n<div id=\"code-block-viewer\" class=\"q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch \u037cs \u037c16\" dir=\"ltr\">\n<div class=\"cm-scroller\">\n<blockquote>\n<div class=\"cm-content q9tKkq_readonly\"><span class=\"\u037c11\">HXSound<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">engines<\/span>(<span class=\"\u037cy\">2<\/span>);<br \/>\n<span class=\"\u037c11\">HXSound<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">reinitialize<\/span>(<span class=\"\u037c11\">context<\/span>);<\/div>\n<div>&nbsp;<\/div>\n<\/blockquote>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p data-start=\"2737\" data-end=\"2871\"><code data-start=\"2737\" data-end=\"2759\">HXSound.engines(int)<\/code> is now ignored on API 21+, and <code data-start=\"2791\" data-end=\"2822\">HXSound.reinitialize(Context)<\/code> is deprecated except for manual reset scenarios.<\/p>\n<h3 data-section-id=\"1qh6jk7\" data-start=\"2873\" data-end=\"2897\">4. Threading Changes<\/h3>\n<p data-start=\"2899\" data-end=\"3039\">Music playback setup now runs through serialized background executors, making playback setup safer and less likely to block the main thread.<\/p>\n<p data-start=\"3041\" data-end=\"3265\">Most existing call sites do not need to change. However, if your app assumes playback setup happens immediately after calling <code data-start=\"3167\" data-end=\"3175\">play()<\/code> or <code data-start=\"3179\" data-end=\"3189\">resume()<\/code>, update that logic to rely on listener callbacks such as <code data-start=\"3247\" data-end=\"3264\">onMusicPrepared<\/code>.<\/p>\n<h3 data-section-id=\"w3hgp0\" data-start=\"3267\" data-end=\"3297\">5. Optional Error Handling<\/h3>\n<p data-start=\"3299\" data-end=\"3357\"><code data-start=\"3299\" data-end=\"3316\">HXMusicListener<\/code> now includes an optional error callback:<\/p>\n<div class=\"relative w-full mt-4 mb-1\">\n<div class=\"\">\n<div class=\"relative\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"border border-token-border-light border-radius-3xl corner-superellipse\/1.1 rounded-3xl\">\n<div class=\"h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse\/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback\">\n<div class=\"relative\">\n<div class=\"\">\n<div class=\"relative z-0 flex max-w-full\">\n<div id=\"code-block-viewer\" class=\"q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch \u037cs \u037c16\" dir=\"ltr\">\n<div class=\"cm-scroller\">\n<blockquote>\n<div class=\"cm-content q9tKkq_readonly\">@<span class=\"\u037c11\">Override<\/span><br \/>\n<span class=\"\u037cv\">public<\/span> <span class=\"\u037cv\">void<\/span> <span class=\"\u037c11\">onMusicError<\/span>(<span class=\"\u037c11\">HXMusicItem<\/span> <span class=\"\u037c11\">music<\/span>, <span class=\"\u037c11\">int<\/span> <span class=\"\u037c11\">what<\/span>, <span class=\"\u037c11\">int<\/span> <span class=\"\u037c11\">extra<\/span>) {<br \/>\n<span class=\"\u037ct\">\/\/ Optional: monitor MediaPlayer failures.<\/span><br \/>\n}<\/div>\n<\/blockquote>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"\">\n<div class=\"\">&nbsp;<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p data-start=\"3498\" data-end=\"3607\">Existing listener implementations should continue to work because this callback has a default implementation.<\/p>\n<h3 data-section-id=\"18jrvoy\" data-start=\"3609\" data-end=\"3636\">6. New Convenience APIs<\/h3>\n<p data-start=\"3638\" data-end=\"3713\">Builder-style playback still works, but v4.0.0 adds simpler helper methods:<\/p>\n<div class=\"relative w-full mt-4 mb-1\">\n<div class=\"\">\n<div class=\"relative\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"border border-token-border-light border-radius-3xl corner-superellipse\/1.1 rounded-3xl\">\n<div class=\"h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse\/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback\">\n<div class=\"relative\">\n<div class=\"\">\n<div class=\"relative z-0 flex max-w-full\">\n<div id=\"code-block-viewer\" class=\"q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch \u037cs \u037c16\" dir=\"ltr\">\n<div class=\"cm-scroller\">\n<blockquote>\n<div class=\"cm-content q9tKkq_readonly\"><span class=\"\u037c11\">HXMusic<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">play<\/span>(<span class=\"\u037c11\">context<\/span>, <span class=\"\u037c11\">R<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">raw<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">my_song<\/span>);<br \/>\n<span class=\"\u037c11\">HXMusic<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">play<\/span>(<span class=\"\u037c11\">context<\/span>, <span class=\"\u037c11\">R<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">raw<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">my_song<\/span>, <span class=\"\u037cy\">true<\/span>);<br \/>\n<span class=\"\u037c11\">HXMusic<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">play<\/span>(<span class=\"\u037c11\">context<\/span>, <span class=\"\u037cz\">&#8220;https:\/\/example.com\/song.mp3&#8221;<\/span>);<br \/>\n<span class=\"\u037c11\">HXMusic<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">playGaplessLoop<\/span>(<span class=\"\u037c11\">context<\/span>, <span class=\"\u037c11\">R<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">raw<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">my_song<\/span>);<br \/>\n<span class=\"\u037c11\">HXSound<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">play<\/span>(<span class=\"\u037c11\">context<\/span>, <span class=\"\u037c11\">R<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">raw<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">my_sound<\/span>);<br \/>\n<span class=\"\u037c11\">HXSound<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">play<\/span>(<span class=\"\u037c11\">context<\/span>, <span class=\"\u037c11\">R<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">raw<\/span><span class=\"\u037cv\">.<\/span><span class=\"\u037c11\">my_sound<\/span>, <span class=\"\u037cy\">true<\/span>);<\/div>\n<\/blockquote>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p data-start=\"3999\" data-end=\"4113\">These are optional shortcuts, so you can migrate gradually without rewriting existing builder-based playback code.<\/p>\n<h3 data-section-id=\"1igk4nn\" data-start=\"4115\" data-end=\"4154\">7. Position Values Use Milliseconds<\/h3>\n<p data-start=\"4156\" data-end=\"4217\"><code data-start=\"4156\" data-end=\"4180\">HXMusicBuilder.at(int)<\/code> expects a value in <strong data-start=\"4200\" data-end=\"4216\">milliseconds<\/strong>.<\/p>\n<p data-start=\"4219\" data-end=\"4231\">For example:<\/p>\n<div class=\"relative w-full mt-4 mb-1\">\n<div class=\"\">\n<div class=\"relative\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"h-full min-h-0 min-w-0\">\n<div class=\"border border-token-border-light border-radius-3xl corner-superellipse\/1.1 rounded-3xl\">\n<div class=\"h-full w-full border-radius-3xl bg-token-bg-elevated-secondary corner-superellipse\/1.1 overflow-clip rounded-3xl lxnfua_clipPathFallback\">\n<div class=\"relative\">\n<div class=\"\">\n<div class=\"relative z-0 flex max-w-full\">\n<div id=\"code-block-viewer\" class=\"q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch \u037cs \u037c16\" dir=\"ltr\">\n<div class=\"cm-scroller\">\n<blockquote>\n<div class=\"cm-content q9tKkq_readonly\">.<span class=\"\u037c11\">at<\/span>(<span class=\"\u037cy\">5000<\/span>) <span class=\"\u037ct\">\/\/ Starts playback at 5 seconds.<\/span><\/div>\n<\/blockquote>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"\">\n<div class=\"\">&nbsp;<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p data-start=\"4289\" data-end=\"4389\" data-is-last-node=\"\" data-is-only-node=\"\">If any older code was passing seconds instead of milliseconds, update those values during migration.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019m excited to announce the release of HXAudioPlayer 4.0.0, the latest major update to this Android audio playback library. HXAudioPlayer is an Android library designed to make audio playback easier to implement by wrapping Android\u2019s MediaPlayer and SoundPool APIs behind a simpler interface. It was originally built for games and<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[534],"tags":[28,612,609,613,490,574,380,575,610,576,611],"class_list":["post-2422","post","type-post","status-publish","format-standard","hentry","category-coding","tag-android","tag-android-app-development","tag-android-audio","tag-audio","tag-chrono-maps","tag-cids-aerial-views","tag-dragon-geo","tag-map-of-the-nocturne","tag-mediaplayer","tag-robot-master-database","tag-soundpool"],"_links":{"self":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts\/2422","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/comments?post=2422"}],"version-history":[{"count":5,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts\/2422\/revisions"}],"predecessor-version":[{"id":2427,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts\/2422\/revisions\/2427"}],"wp:attachment":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/media?parent=2422"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/categories?post=2422"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/tags?post=2422"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}