<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Alessandro Crugnola &#8211; sephiroth.it</title>
	<atom:link href="https://blog.sephiroth.it/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.sephiroth.it</link>
	<description>programmer by pure chance</description>
	<lastBuildDate>Sun, 23 Oct 2022 17:43:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blog.sephiroth.it/wp-content/uploads/2019/03/cropped-sepy-big-32x32.png</url>
	<title>Alessandro Crugnola &#8211; sephiroth.it</title>
	<link>https://blog.sephiroth.it</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Android: pipe(&#8220;&#124;&#8221;) and ProcessBuilder</title>
		<link>https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/</link>
					<comments>https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/#respond</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Sat, 22 Oct 2022 12:32:03 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[general]]></category>
		<category><![CDATA[kotlin]]></category>
		<guid isPermaLink="false">https://blog.sephiroth.it/?p=1856</guid>

					<description><![CDATA[How to implement a pipe between processes in android using kotlin.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As of today there&#8217;s no public implementation of the java <a rel="noreferrer noopener" href="https://docs.oracle.com/javase/9/docs/api/java/lang/ProcessBuilder.html#startPipeline-java.util.List-" target="_blank">ProcessBuilder.startPipeline</a> in Android.</p>



<p class="wp-block-paragraph">So I came out with this quick solution, using <strong>Kotlin</strong>, to pipe multiple processes in Android:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">object ProcessUtil {
    private fun check(process: Process, error: (() -> String)) {
        try {
            if (process.errorStream.available() > 0) {
                process.errorStream.bufferedReader().use {
                    it.readText().also { errorText ->
                        check(errorText.isBlank()) { "${error.invoke()} failed with error: $errorText" }
                    }
                }
            }
        } catch (_: IOException) {
            // ignore
        }
    }

    @Throws(IOException::class, IllegalStateException::class)
    fun pipe(vararg processes: ProcessBuilder): String {
        check(processes.size > 1) { "At least 2 processes are required" }

        var previous: Process? = null
        var result: String = ""

        processes.forEachIndexed { index, builder ->
            val cmdString = builder.command().joinToString(" ")
            println("Executing command $index -> $cmdString")

            if (index > 0) {
                check(builder.redirectInput() == Redirect.PIPE) { "Builder redirectInput must be PIPE except for the first builder" }
            } else if (index &lt; processes.size - 1) {
                check(builder.redirectOutput() == Redirect.PIPE) { "Builder redirectOutput must be PIPE except for the last builder" }
            }

            val current: Process = builder.start()
            check(current) { cmdString }

            previous?.let { prevProcess ->
                prevProcess.inputStream.bufferedReader().use { reader ->
                    current.outputStream.bufferedWriter().use { writer ->
                        reader.readLines().forEach { line ->
                            println("writing --> $line")
                            writer.write(line)
                            writer.newLine()
                        }
                        check(current) { cmdString }

                    } // writer

                    if (index == processes.size - 1) {
                        current.inputStream.bufferedReader().use { reader2 ->
                            result = reader2.readText()
                        }
                    }

                } // reader
            }
            previous = current
        }
        return result
    }

    fun pipe(vararg commands: List&lt;String>) = pipe(*commands.map { ProcessBuilder(it) }.toTypedArray())

    fun pipe(vararg commands: String) = pipe(*commands.map { ProcessBuilder(it) }.toTypedArray())
}</pre>



<p class="wp-block-paragraph">And it can be used like this:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    @Test
    fun testPipe() {
        val packageName = context.packageName
        val result = ProcessUtil.pipe(listOf("ps", "-A"), listOf("grep", packageName), listOf("awk", "{ print $9 }"))
        println("result = '$result'")
        Assert.assertTrue(result.contains(packageName))
    }</pre>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1856 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Android%3A+pipe%28%E2%80%9C%7C%E2%80%9D%29+and+ProcessBuilder&url=https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/&title=Android%3A+pipe%28%E2%80%9C%7C%E2%80%9D%29+and+ProcessBuilder" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2022/10/22/android-pipe-and-processbuilder/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Photoshop Extension: Opacity Editor</title>
		<link>https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/</link>
					<comments>https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/#respond</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Sat, 29 Sep 2018 00:16:37 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[general]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[layers]]></category>
		<category><![CDATA[opacity]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[photoshop]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1739</guid>

					<description><![CDATA[Today I&#8217;d like to introduce an extension I&#8217;ve created for Adobe Photoshop: Opacity Editor. I like to take pictures, ok, I&#8217;m definitely not a professional photographer, but I still like to try to be one &#240;&#159;&#153;&#130; In particular I like to take pictures at night, I like to take pictures of moving clouds, stars.. etc. &#8230; <a href="https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/" class="more-link">Continue reading <span class="screen-reader-text">Photoshop Extension: Opacity Editor</span></a>]]></description>
										<content:encoded><![CDATA[<p>Today I&#8217;d like to introduce an extension I&#8217;ve created for <strong>Adobe Photoshop: Opacity Editor.</strong></p>
<p>I like to take pictures, ok, I&#8217;m definitely not a professional photographer, but I still like to try to be one 🙂</p>
<p>In particular I like to take pictures at night, I like to take pictures of moving clouds, stars.. etc. And then I like to stack all the photos into a single document. The problem is that most of the times this Photoshop document has hundreds, if not thousands, of layers (and we&#8217;re talking about 40MP images) and, despite the fact that photoshop can barely survive after I&#8217;ve added all those layers to the document, the real problem comes after that.. In order to create a nice stacking effect it&#8217;s not just a matter of changing the blending mode of the different layers, but also to change their opacity.</p>
<p>Unfortunately Photoshop doesn&#8217;t have an option to manage the opacity of multiple layers at the same time, like, for instance, from 0 to 100 of all the selected layers.. or even more advanced options.</p>
<p>That&#8217;s why I&#8217;ve decided to make an extension (<a href="https://www.adobeexchange.com/creativecloud.details.20327.html">available here</a>) for this. This is it&#8217;s pretty easy interface:</p>
<p><a href="http://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor.png"><img fetchpriority="high" decoding="async" class="size-medium wp-image-1740 alignnone" src="http://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-300x233.png" alt="" width="300" height="233" srcset="https://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-300x233.png 300w, https://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-522x406.png 522w, https://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor.png 595w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>So basically what it does is: you select a bunch of layers in your document, then you create the bezier curve. Once you click on &#8220;Apply Opacity&#8221; the opacity of every selected layer will follow the designed curve value. Let&#8217;s make it easier. If you design a curve like this:</p>
<p><a href="http://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-2.png"><img decoding="async" class="size-medium wp-image-1745 alignnone" src="http://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-2-300x233.png" alt="" width="300" height="233" srcset="https://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-2-300x233.png 300w, https://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-2-522x406.png 522w, https://blog.sephiroth.it/wp-content/uploads/2018/09/opacity-editor-2.png 595w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>the first selected layer will have an opacity of 0 (completely invisible), while the last layer will have 100 as opacity. (If you&#8217;ve selected 100 layers, then the second one will have an opacity value of 1, the third of 2 and so on..)</p>
<p>These 2 images, for instance, have been created using this extension:</p>
<p>&nbsp;</p>
<table style="border-collapse: collapse; width: 100%; height: 225px;" border="0">
<tbody>
<tr style="height: 225px;">
<td style="width: 50%; height: 225px;"><a href="http://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1.jpg"><img decoding="async" class="aligncenter size-medium wp-image-1742" src="http://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1-300x200.jpg" alt="" width="300" height="200" srcset="https://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1-300x200.jpg 300w, https://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1-768x513.jpg 768w, https://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1-1024x684.jpg 1024w, https://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1-608x406.jpg 608w, https://blog.sephiroth.it/wp-content/uploads/2018/09/Jordan-Pond-1.jpg 1600w" sizes="(max-width: 300px) 100vw, 300px" /></a></td>
<td style="width: 50%; height: 225px;">
<p><figure id="attachment_1743" aria-describedby="caption-attachment-1743" style="width: 300px" class="wp-caption aligncenter"><a href="http://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB.jpg"><img loading="lazy" decoding="async" class="size-medium wp-image-1743" src="http://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB-300x193.jpg" alt="" width="300" height="193" srcset="https://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB-300x193.jpg 300w, https://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB-768x494.jpg 768w, https://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB-1024x659.jpg 1024w, https://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB-631x406.jpg 631w, https://blog.sephiroth.it/wp-content/uploads/2018/09/DSC5546-Edit-2-sRGB.jpg 1600w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-1743" class="wp-caption-text">1200~ pics</figcaption></figure></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>The second one is the result of 1200 layers stacked together and without that extension I would probably still working on it!</p>
<p>And here&#8217;s an example of the Extension in action:</p>
<table style="border-collapse: collapse; width: 100%;" border="0">
<tbody>
<tr>
<td style="width: 100%; text-align: center;"><iframe loading="lazy" src="//www.youtube.com/embed/jW3uDrZoIzI" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>For more information and download:<br />
<a href="https://www.adobeexchange.com/creativecloud.details.20327.html">https://www.adobeexchange.com/creativecloud.details.20327.html</a></p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1739 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Photoshop+Extension%3A+Opacity+Editor&url=https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/&title=Photoshop+Extension%3A+Opacity+Editor" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2018/09/29/photoshop-extension-opacity-editor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why it&#8217;s hard to find Android developers</title>
		<link>https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/</link>
					<comments>https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/#comments</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Tue, 16 Sep 2014 07:30:41 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[new york]]></category>
		<category><![CDATA[startups]]></category>
		<category><![CDATA[tech]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1694</guid>

					<description><![CDATA[I&#8217;m an Android developer (at Aviary) and a New Yorker since&#160;late 2010. I&#8217;ve been also an actionscript and python developer for more than 10 years. I hear this every day. Your New York based company is desperately&#160;looking for an Android developer, and it&#8217;s damn hard to find one. And you know what? This is your &#8230; <a href="https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/" class="more-link">Continue reading <span class="screen-reader-text">Why it&#8217;s hard to find Android developers</span></a>]]></description>
										<content:encoded><![CDATA[<blockquote>
<p class="p1">I&#8217;m an Android developer (at <a href="https://aviary.com/" target="_blank" rel="noopener">Aviary</a>) and a New Yorker since&nbsp;late 2010. I&#8217;ve been also an actionscript and python developer for more than 10 years.</p>
</blockquote>
<p class="p1">I hear this every day. Your New York based company is desperately&nbsp;looking for an Android developer, and it’s damn hard to find one.</p>
<p class="p1">And you know what? <strong>This is your fault</strong>. I mean you, tech startup. Yes, you.</p>
<p class="p1">Almost all the startups I know here in NYC have launched their core product for iOS first (most of the PMs I’ve spoken with have said that was because of lack of people or time).&nbsp;And then, maybe, if there&#8217;s time… they start to realize they need to have an Android version of their app. But by this point the job is not to &#8220;create” something, it’s just a “porting” job. Which, for obvious reasons, is a much less attractive job for developers, just as it would be for a PM or a designer.<span id="more-1694"></span></p>
<p class="p1">Anyway, ignoring Android at first is somewhat understandable, if you think in short terms and you’re not thinking globally.&nbsp;Here in the US, and even more in NYC, the iOS market share is still very strong: as of this past May,&nbsp;Android has 50% of the share and iOS has 42% nationwide (<a href="https://www.comscore.com/ita/Insights/Market-Rankings/comScore-Reports-May-2014-U.S.-Smartphone-Subscriber-Market-Share"><span class="s1">https://www.comscore.com/ita/Insights/Market-Rankings/comScore-Reports-May-2014-U.S.-Smartphone-Subscriber-Market-Share</span></a>).<br />
If you remove the huge number of “low end” (not profitable) devices from the Android share &#8211; as most people do &#8211; you’ll see why I said I can understand it.</p>
<p class="p1">But, that said, I don’t agree with it. Because globally, for the rest of the world, things are completely different. Android has 80% of the market share and iOS only has around 12% (<a href="http://www.idc.com/prodserv/smartphone-os-market-share.jsp"><span class="s1">http://www.idc.com/prodserv/smartphone-os-market-share.jsp</span></a>).</p>
<p class="p1"><b>Ok, I know the numbers, but why is hard to find Android developers?</b><br />
Because you are not committed to Android development.&nbsp;You just think you “have” to do that. Because at some point you realize either that you need it to go global, or because a lot of users are asking it, or just because you think that porting your app will double your users overnight.</p>
<p class="p1">But you’re not committed to doing it.</p>
<p class="p1">And when you start, most of the time it’s with a 1-to-1 porting of your iOS app, or at the very best a porting of UI created ad hoc for an iOS environment, which cannot be applied to Android (although, to your credit, you probably don’t know this because you didn&#8217;t bother hiring an Android PM or UX expert). I don’t think I even need to mention the cases where you&#8217;ve already given the initial porting to 3rd party companies&#8230;</p>
<p class="p1">Then, after all of this, you complain because the response of the Android market is not as good as you expected and the profits are not comparable to iOS. Well, I would be extremely surprised if this weren&#8217;t the case. You’re not committed to it, and you didn&#8217;t build an app that takes advantage of any of the benefits of the platform, so what do you expect?</p>
<p class="p1">(When I say committed, I mean all the departments in your company from top to bottom. You can’t say you’re committed to it just because you have an Android team. The whole company needs to acknowledge that it&#8217;s a priority.)</p>
<p class="p1"><b>Ok, but I still don’t get why it’s hard to find Android developers.</b><br />
Well, try to think from a developer&#8217;s perspective.&nbsp;Android developers don’t find it very attractive to join a company where Android will be always the 2nd choice. That’s very frustrating.</p>
<p class="p1">And as for developers who are approaching the mobile market for the first time, which platform do you think they’ll choose?&nbsp;They see all of your apps being introduced on iOS first, they see that the Android version is not as good as the iOS one, and they see you complaining about the Android market.</p>
<p class="p1"><strong>So, why should they choose Android? And why should they choose your company if they do?</strong></p>
<p class="p1">Here are some suggestions for ways that you can help:</p>
<ul class="ul1">
<li class="li1">Switch to Android (temporarily, if you want). Get to know the platform. Understand why some people prefer it. Read some articles about purchasing habits of the users. Understand the differences between ios and android. Etc.</li>
<li class="li1">Commit to Android as a platform. Talk openly at your company (and externally) about the market share, the benefits of the platform, and think about ways it can help your product &#8211; so that when an Android developer does join, he or she has some interesting projects to work on.</li>
<li class="li1">Offer a signing bonus to developers who switch to Android for your company.</li>
<li class="li1">Launch your next product on Android first (or at the same time as iOS).</li>
<li class="li1">Attend Android meetups. Speak at Android meetups! Encourage the developers you work with to do the same.</li>
</ul>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1694 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Why+it%E2%80%99s+hard+to+find+Android+developers&url=https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/&title=Why+it%E2%80%99s+hard+to+find+Android+developers" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2014/09/16/why-its-hard-to-find-android-developers/feed/</wfw:commentRss>
			<slash:comments>50</slash:comments>
		
		
			</item>
		<item>
		<title>Android &#8211; Create a Vignette effect</title>
		<link>https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/</link>
					<comments>https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/#respond</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Sun, 06 Jul 2014 03:32:17 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[radialgradient]]></category>
		<category><![CDATA[shader]]></category>
		<category><![CDATA[vignette]]></category>
		<category><![CDATA[xfermode]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1685</guid>

					<description><![CDATA[Let&#8217;s say you want to want to dynamically&#160;apply a &#8220;vignette&#8221; on an ImageView. Something like this: These are basically 4&#160;steps we need in order to accomplish the task: Create a Paint using the&#160;PorterDuff.Mode.DST_OUT as&#160;Xfermode Create a RadialGradient and assign to our Paint object as a Shader Alter the gradient matrix using the&#160;setLocalMatrix method. Use&#160;canvas.saveLayer when &#8230; <a href="https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/" class="more-link">Continue reading <span class="screen-reader-text">Android &#8211; Create a Vignette effect</span></a>]]></description>
										<content:encoded><![CDATA[<p>Let&#8217;s say you want to want to dynamically apply a &#8220;vignette&#8221; on an <a href="http://developer.android.com/reference/android/widget/ImageView.html">ImageView</a>.<br />
Something like this:</p>
<table style="height: 300px;" width="100%">
<tbody>
<tr>
<td><img loading="lazy" decoding="async" src="http://blog.sephiroth.it/wp-content/uploads/2014/07/Screenshot_2014-07-05-22-30-30-168x300.png" alt="Screenshot_2014-07-05-22-30-30" width="168" height="300" hspace="20" /></td>
</tr>
</tbody>
</table>
<p>These are basically 4 steps we need in order to accomplish the task:<br />
<span id="more-1685"></span></p>
<ol>
<li>Create a Paint using the <a href="http://developer.android.com/reference/android/graphics/PorterDuff.Mode.html">PorterDuff.Mode</a>.DST_OUT as Xfermode</li>
<li>Create a <a href="http://developer.android.com/reference/android/graphics/RadialGradient.html">RadialGradient</a> and assign to our Paint object as a Shader</li>
<li>Alter the gradient matrix using the setLocalMatrix method.</li>
<li>Use canvas.saveLayer when drawing</li>
</ol>
<h3>1. Paint using PorterDuff.Mode.DST_OUT</h3>
<p>This is needed in order to draw an &#8220;hole&#8221; in our back background.</p>
<pre>
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
</pre>
<h3>2. Create the RadialGradient shader:</h3>
<p>This is required in order to draw a radial gradient &#8220;hole&#8221; in our black background. Thus revealing the background image using a &#8220;vignette&#8221; filter.</p>
<pre>
final int[] colors = new int[]{0xff000000, 0xff000000, 0};
final float[] anchors = new float[]{0, 0.5f, 1};
Shader shader = new android.graphics.RadialGradient(0, 0, 1, colors, anchors, Shader.TileMode.CLAMP);
paint.setShader(shader);
</pre>
<h3>3. Alter the gradient matrix</h3>
<p>The again, in order to create a real vignette effect we need to draw a custom &#8220;oval&#8221;, otherwise the result of draw something using the radialgradient shader will result in a simple circle. Instead, if we alter its matrix we can modify its aspect ratio, giving it the oval shape:</p>
<pre>
Matrix matrix = new Matrix();
matrix.postTranslate(rect.centerX(), rect.centerY());
matrix.postScale(rect.width() / 2, rect.height() / 2, rect.centerX(), rect.centerY());
shader.setLocalMatrix(matrix);
</pre>
<h3>4. Draw on a canvas</h3>
<p>Now we need to draw our objects on a real canvas. We need to save the current layer using <a href="http://developer.android.com/reference/android/graphics/Canvas.html#saveLayer(android.graphics.RectF,%20android.graphics.Paint, int)">Canvas.saveLayer</a> because otherwise everything we previously drawn will be erased by our paint. But because we&#8217;re using saveLayer, we actually are drawing on an offscreen bitmap.</p>
<pre>
// save current status
// 'pBitmapRect' is the current Bitmap rectangle
canvas.saveLayer(pBitmapRect, mPaint, Canvas.ALL_SAVE_FLAG);
// draw the black background
canvas.drawRect(pBitmapRect, mBlackPaint);
// draw the vignette on the black background using our radial gradient
canvas.drawOval(tempRect2, mPaintShader);
canvas.restore();
</pre>
<h2>Source Code</h2>
<p>You can download the complete source code here:<br />
<a href="https://github.com/sephiroth74/vignette_demo">https://github.com/sephiroth74/vignette_demo</a></p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1685 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Android+%E2%80%93+Create+a+Vignette+effect&url=https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/&title=Android+%E2%80%93+Create+a+Vignette+effect" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2014/07/06/android-create-a-vignette-effect/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Floating Action Menu for Android</title>
		<link>https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/</link>
					<comments>https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/#comments</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Sun, 25 May 2014 06:10:46 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[opensource]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1679</guid>

					<description><![CDATA[I&#8217;ve just created this simple Android library, inspired from the recent changes to the Google+ app, which introduced a floating action item to the bottom. In G+ the action item appears and disappears based on the page scrolling. In the same way I&#8217;ve created this library, with some more customization options, like the gravity and &#8230; <a href="https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/" class="more-link">Continue reading <span class="screen-reader-text">Floating Action Menu for Android</span></a>]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve just created this simple Android library, inspired from the recent changes to the Google+ app, which introduced a floating action item to the bottom. In G+ the action item appears and disappears based on the page scrolling.</p>
<p>In the same way I&#8217;ve created this library, with some more customization options, like the gravity and direction of the floating menu items.</p>
<p>Here&#8217;s a video of a sample implementation:</p>
<p><iframe loading="lazy" src="//www.youtube.com/embed/mLplXAJ5vug" width="400" height="711"></iframe></p>
<p>Source code and documentation can be find on the github project page:</p>
<p><a href="https://github.com/sephiroth74/android-floating-action-menu" target="_blank">https://github.com/sephiroth74/android-floating-action-menu</a></p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1679 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Floating+Action+Menu+for+Android&url=https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/&title=Floating+Action+Menu+for+Android" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2014/05/25/floating-action-menu-for-android/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>java.lang.UnsatisfiedLinkError workaround</title>
		<link>https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/</link>
					<comments>https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/#comments</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Sat, 12 Apr 2014 04:21:52 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[chromium]]></category>
		<category><![CDATA[packagemanager]]></category>
		<category><![CDATA[UnsatisfiedLinkError]]></category>
		<category><![CDATA[workaround]]></category>
		<category><![CDATA[xperia]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1668</guid>

					<description><![CDATA[If you ever worked with native shared libraries in Android you&#8217;ve probably already faced the &#8220;java.lang.UnsatisfiedLinkError&#8221; java exception which randomly seems to happen on certain devices ( actually it&#8217;s happening on xperia phones mostly, based on my reports ). There are a bunch of bug reports in the android project like this: https://code.google.com/p/android/issues/detail?id=35962 or this &#8230; <a href="https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/" class="more-link">Continue reading <span class="screen-reader-text">java.lang.UnsatisfiedLinkError workaround</span></a>]]></description>
										<content:encoded><![CDATA[<p>If you ever worked with native shared libraries in Android you&#8217;ve probably already faced the <strong>&#8220;java.lang.UnsatisfiedLinkError&#8221;</strong> java exception which randomly seems to happen on certain devices ( actually it&#8217;s happening on <strong>xperia</strong> phones mostly, based on my reports ).<br />
There are a bunch of bug reports in the android project like this: <a href="https://code.google.com/p/android/issues/detail?id=35962" target="_blank">https://code.google.com/p/android/issues/detail?id=35962</a> or this <a href="https://code.google.com/p/android/issues/detail?id=64111" target="_blank">https://code.google.com/p/android/issues/detail?id=64111</a>.<br />
The problem is that Google basically marked all of them as &#8220;resolved&#8221;, even if developers are still complaining about it.</p>
<p><span id="more-1668"></span></p>
<p>The fun thing is that it seems that they are aware of the problem and in fact they&#8217;re trying to use a workaround internally in the chromium source code.<br />
For instance, this is the first workaround I found:<br />
<a href="https://codereview.chromium.org/180273005/patch/80001/90003" target="_blank">https://codereview.chromium.org/180273005/patch/80001/90003</a></p>
<p>which is basically looking into the <em>&#8220;/data/app-lib/{packagename}-1/&#8221;</em> folder for the missing libraries.<br />
And in fact, inside the comments of that file you can read this:</p>
<blockquote><p><cite>Native library directory in an updated package is a symbolic link<br />
to a directory in /data/app-lib/, for example:<br />
/data/data/com.android.chrome/lib -&gt; /data/app-lib/com.android.chrome[-1].<br />
When updating the application, the PackageManager create a new directory,<br />
e.g., /data/app-lib/com.android.chrome-2, and remove the old symlink and<br />
recreate one to the new directory. However, on some devices (e.g. Sony Xperia),<br />
the old directory was deleted, but deleting the old symlink failed,<br />
and that makes system loading library from the /system/lib directory.</cite></p></blockquote>
<p>Then I noticed another approach which is probably better: <a href="http://goo.gl/cbCAmC">http://goo.gl/cbCAmC</a></p>
<p>which is basically doing what the PackageManager was supposed to do, unzip the shared libraries from the apk file to the &#8220;lib&#8221; dir of the application itself.</p>
<p>Btw, I&#8217;m gonna try both of them and verify if they actually work so I can finally stop seeing that annoying bug in the Google Play Console!</p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1668 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=java.lang.UnsatisfiedLinkError+workaround&url=https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/&title=java.lang.UnsatisfiedLinkError+workaround" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2014/04/12/java-lang-unsatisfiedlinkerror-workaround/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>More Picasso changes</title>
		<link>https://blog.sephiroth.it/2014/01/28/more-picasso-changes/</link>
					<comments>https://blog.sephiroth.it/2014/01/28/more-picasso-changes/#comments</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Tue, 28 Jan 2014 20:28:24 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[picasso]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1663</guid>

					<description><![CDATA[I recently added more changes to my forked version of the Picasso library. Delay Added withDelay(long ms) method in the RequestCreator class. Basically it will delay the load of the passed resource by n milliseconds. [cce] Picasso.with( context ) .load( url ) .withDelay( 100 ) .into( image ); [/cce] Batch toggle on/off In the original &#8230; <a href="https://blog.sephiroth.it/2014/01/28/more-picasso-changes/" class="more-link">Continue reading <span class="screen-reader-text">More Picasso changes</span></a>]]></description>
										<content:encoded><![CDATA[<p>I recently added more changes to my <a href="https://github.com/sephiroth74/picasso">forked</a> version of the <a href="https://github.com/square/picasso">Picasso</a> library.</p>
<p><strong>Delay</strong></p>
<p>Added <em>withDelay(long ms)</em> method in the RequestCreator class. Basically it will delay the load of the passed resource by <strong><em>n</em></strong> milliseconds.</p>
<p>[cce]<br />
Picasso.with( context )<br />
	.load( url )<br />
	.withDelay( 100 )<br />
	.into( image );<br />
[/cce]</p>
<p><strong>Batch toggle on/off</strong></p>
<p>In the original Picasso code all the &#8220;complete&#8221; events are dispatched using a batch operation, this means that you can have at the same time 3/4 &#8220;complete&#8221; events being triggered, which eventually can cause lags in the UI.<br />
In this fork the batch is disabled by default and can be re-enabled by using:</p>
<p>[cce]<br />
Picasso.with( context )<br />
	.setUseBatch( true );<br />
[/cce]</p>
<p>Fork or download the source from GitHub: <br />
<a href="https://github.com/sephiroth74/picasso">https://github.com/sephiroth74/picasso</a></p>
<p>Link the library in your build.gradle:<br /> <strong>compile &#8220;it.sephiroth.android.library.picasso:picasso:+&#8221;</strong></p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1663 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2014/01/28/more-picasso-changes/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=More+Picasso+changes&url=https://blog.sephiroth.it/2014/01/28/more-picasso-changes/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2014/01/28/more-picasso-changes/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2014/01/28/more-picasso-changes/&title=More+Picasso+changes" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2014/01/28/more-picasso-changes/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2014/01/28/more-picasso-changes/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Forking Picasso</title>
		<link>https://blog.sephiroth.it/2013/10/16/forking-picasso/</link>
					<comments>https://blog.sephiroth.it/2013/10/16/forking-picasso/#comments</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Wed, 16 Oct 2013 18:12:50 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[picasso]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1651</guid>

					<description><![CDATA[Recently I started using this nice library, Picasso, for my Android projects. Basically it&#8217;s a library which allows you to load any type of images (local or remote, assets or resources) asynchronously&#160;into your ImageView. It will load them in background for you, this not blocking the UI. It has also an internal cache system and &#8230; <a href="https://blog.sephiroth.it/2013/10/16/forking-picasso/" class="more-link">Continue reading <span class="screen-reader-text">Forking Picasso</span></a>]]></description>
										<content:encoded><![CDATA[<p>Recently I started using this nice library, <a href="https://github.com/square/picasso" target="_blank">Picasso</a>, for my Android projects.<br />
Basically it&#8217;s a library which allows you to load any type of images (local or remote, assets or resources) asynchronously into your ImageView. It will load them in background for you, this not blocking the UI. It has also an internal cache system and it also comes with some useful features like &#8220;fade&#8221; ( when an image is loaded into the view it will automatically create a fade in effect ), &#8220;transform&#8221; ( you want to post transform the loaded bitmap ), &#8220;resize&#8221;, &#8220;fit&#8221; and more.</p>
<p>You can find a better explanation of the project here: <a href="http://square.github.io/picasso/">http://square.github.io/picasso/</a></p>
<p>By the way, long story short, as often happens, when you start to use a 3rd party library you also find it&#8217;s limitations and you want to make your own changes to fit your particular needs. In fact I made a <a href="https://github.com/sephiroth74/picasso" target="_blank">fork</a> of this library starting adding my changes.</p>
<p>Here&#8217;s a first list of changes I made:</p>
<p><strong>Cache</strong></p>
<p>Added the possibility to use an external cache instance per request.<br />
Example:</p>
<p>[cce]// creating a cache object with 1MB max size<br />
Cache cache = new LruCache( 1024*1024*1 );</p>
<p>// now create a new request which will use this cache object<br />
Picasso.with( this ).load( file ).withCache( myCache ).into( imageView );[/cce]</p>
<blockquote><p>Remember to clear the cache when you don&#8217;t need that anymore ( using cache.clear() )</p></blockquote>
<p><strong>Generators</strong></p>
<p>Generators can be used to load images which cannot be loaded using the common scheme convention. There are different situations when you need to generate a Bitmap which is not directly related to a file or url or even a real bitmap resource.</p>
<p>In this case you can use the scheme &#8220;custom.resource&#8221; with a Generator.<br />
A Generator is a simple interface with only one method:</p>
<p>[cce]public interface Generator {<br />
	Bitmap decode( String path ) throws IOException;<br />
}[/cce]</p>
<p>So you can use a generator in this way:</p>
<p>[cce]Picasso.with(this)<br />
	.load( Uri.parse( &#8220;custom.resource://&#8221; + file ) )<br />
	.withGenerator( new Generator() {<br />
		@Override<br />
			public Bitmap decode( String path ) throws IOException {<br />
				return whatever(path);<br />
			}<br />
		} ).into( imageView );<br />
[/cce]</p>
<p><strong>Resize</strong></p>
<p>Both the original Picasso methods resize and resizeDimen have been modified in the followings new methods:</p>
<p>[cce]public RequestCreator resizeDimen(int targetWidthResId, int targetHeightResId, boolean onlyIfBigger);<br />
public RequestCreator resize(int targetWidth, int targetHeight, boolean onlyIfBigger);[/cce]</p>
<p>basically you can pass an option to skip the resize operation if the loaded bitmap is smaller than the passed `targetWidth` and `targetHeight`</p>
<p><strong>BitmapFactory.Options</strong></p>
<p>Picasso uses a default BitmapFactory.Options object, every time, to decode the required Bitmap.</p>
<p>I&#8217;ve added a method `withOptions` in the RequestCreator which allow you to pass your own Options object which will be used to decode the image.<br />
Example:</p>
<p>[cce]BitmapFactory.Options options = new BitmapFactory.Options();<br />
options.inPreferredConfig = Config.RGB_565;</p>
<p>Picasso.with(this)<br />
	.load(file)<br />
	.withOptions(options)<br />
	.into(imageView);<br />
[/cce]</p>
<p><a href="https://github.com/sephiroth74/picasso" target="_blank">https://github.com/sephiroth74/picasso</a></p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1651 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2013/10/16/forking-picasso/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Forking+Picasso&url=https://blog.sephiroth.it/2013/10/16/forking-picasso/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2013/10/16/forking-picasso/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2013/10/16/forking-picasso/&title=Forking+Picasso" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2013/10/16/forking-picasso/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2013/10/16/forking-picasso/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Obtain styleable fields at runtime</title>
		<link>https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/</link>
					<comments>https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/#respond</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Fri, 11 Oct 2013 13:13:36 +0000</pubDate>
				<category><![CDATA[android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[reflection]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1647</guid>

					<description><![CDATA[Ususally, when we want to get some &#8220;R&#8221; attributes at runtime, we use the Resources getIdentifier method, which is useful for getting strings, drawables and ids at runtime. Unfortunately this method cannot be used to get the styleable fields. However, using java reflections, there&#8217;s another way to solve the problem. With this snippet you can &#8230; <a href="https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/" class="more-link">Continue reading <span class="screen-reader-text">Obtain styleable fields at runtime</span></a>]]></description>
										<content:encoded><![CDATA[<p>Ususally, when we want to get some “R” attributes at runtime, we use the Resources getIdentifier method, which is useful for getting strings, drawables and ids at runtime. Unfortunately this method cannot be used to get the styleable fields. However, using java <a href="http://docs.oracle.com/javase/tutorial/reflect/" target="_blank">reflections</a>, there’s another way to solve the problem. With this snippet you can get styleable fields at runtime in your code:</p>
<p>[cce]public static final &lt;T&gt; T getFieldFromStyleable( Context context, String name ) {<br />
    try {<br />
		// use reflection to access the resource class<br />
		Field field = Class.forName( context.getPackageName() + &#8220;.R$styleable&#8221; ).getField( name );<br />
		if ( null != field ) {<br />
			return (T) field.get( null );<br />
		}<br />
	} catch ( Throwable t ) {<br />
		t.printStackTrace();<br />
	}<br />
	return null;<br />
}[/cce]</p>
<p>Which can be used in this way:<br />
[cce]int[] array = getFieldFromStyleable( context, &#8220;MyListView&#8221; );<br />
array = context.obtainStyledAttributes( attrs, styleableArray, defStyle, 0 );[/cce]</p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1647 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=Obtain+styleable+fields+at+runtime&url=https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/&title=Obtain+styleable+fields+at+runtime" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2013/10/11/obtain-styleable-fields-at-runtime/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>purePDF moved to github</title>
		<link>https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/</link>
					<comments>https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/#comments</comments>
		
		<dc:creator><![CDATA[Alessandro Crugnola]]></dc:creator>
		<pubDate>Mon, 18 Mar 2013 14:10:28 +0000</pubDate>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[purePDF]]></category>
		<category><![CDATA[github]]></category>
		<guid isPermaLink="false">http://blog.sephiroth.it/?p=1638</guid>

					<description><![CDATA[As you may have noticed I&#8217;m not working with flash and actionscript anymore. However I still receive some requests regarding the purePDF library I published, well I don&#8217;t remember when exactly &#240;&#159;&#153;&#130; By the way, I decided to move the code to github, thus it will be easier for anyone still interested in that library &#8230; <a href="https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/" class="more-link">Continue reading <span class="screen-reader-text">purePDF moved to github</span></a>]]></description>
										<content:encoded><![CDATA[<p>As you may have noticed I&#8217;m not working with flash and actionscript anymore. However I still receive some requests regarding the <a href="https://code.google.com/p/purepdf/"><strong>purePDF</strong></a> library I published, well I don&#8217;t remember when exactly 🙂<br />
By the way, I decided to move the code to <a href="https://github.com/sephiroth74/purePDF">github</a>, thus it will be easier for anyone still interested in that library to fork and add modifications and share to other people.</p>
<p>Here&#8217;s the link to the project: <strong><a href="https://github.com/sephiroth74/purePDF">https://github.com/sephiroth74/purePDF</a></strong></p>
<span class=" ssb_inline-share_heading left">Share with...</span><div class="simplesocialbuttons simplesocial-round-btm-border simplesocialbuttons_inline simplesocialbuttons-align-left post-1638 post  simplesocialbuttons-inline-no-animation">
<button class="simplesocial-fb-share"  rel="nofollow"  target="_blank"  aria-label="Facebook Share" data-href="https://www.facebook.com/sharer/sharer.php?u=https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Facebook </span> </button>
<button class="simplesocial-twt-share"  rel="nofollow"  target="_blank"  aria-label="Twitter Share" data-href="https://twitter.com/intent/tweet?text=purePDF+moved+to+github&url=https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/&via=sephiroth74" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">Twitter</span> </button>
<button  rel="nofollow"  target="_blank"  class="simplesocial-linkedin-share" aria-label="LinkedIn Share" data-href="https://www.linkedin.com/sharing/share-offsite/?url=https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><span class="simplesocialtxt">LinkedIn</span></button>
<button class="simplesocial-reddit-share"  rel="nofollow"  target="_blank"  aria-label="Reddit Share" data-href="https://reddit.com/submit?url=https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/&title=purePDF+moved+to+github" onClick="javascript:window.open(this.dataset.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" ><span class="simplesocialtxt">Reddit</span> </button>
<button onClick="javascript:window.open(this.dataset.href, '_blank' );return false;" class="simplesocial-whatsapp-share"  rel="nofollow"  target="_blank"  aria-label="WhatsApp Share" data-href="https://api.whatsapp.com/send?text=https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/"><span class="simplesocialtxt">WhatsApp</span></button>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.sephiroth.it/2013/03/18/purepdf-moved-to-github/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
